phpbar.de logo

Mailinglisten-Archive

[php] mehrdimensionales array sortieren?

[php] mehrdimensionales array sortieren?

Ulf Wendel ulf_(at)_redsys.de
Thu, 27 Jan 2000 11:49:06 +0000


Christof Beaupoil wrote:
> ich würde gerne ein 2dimensionales array sortieren. Das Handbuch bietet
> bei "sort()" aber nur Beispielcode für eindimensionale arrays. Wie geht
> das und kann ich nach einer beliebigen "Spalte" sortieren?

Eigentlich sollte man hierfür usort verwenden, aber diese Funktion
crasht in der aktuellen Version
http://www.php.net/manual/function.usort.php3. Also schreibt greift man
auf Hausmittel zurück.

> 
> Mein array:
> 
> $array2d = array(
>     "erste_zeile"  => array(2, 4, 6, 7, 9, 8),
>     "zweite_zeile" => array(1, 2, 3, 4, 5, 6),
>     "dritte_zeile" => array(3, 4, 3, 2, 6, 8)
> );
> 
> Das Teil würde ich gerne sortieren und dann ausgeben:
> 
> 1 2 3 4 5 6
> 2 4 6 7 9 8
> 3 4 3 2 6 8

Ein Ansatz besteht in der Isolierung der n-ten Spalte, ihrer Sortierung
und dem anschließenden zurückkopieren. Sehr performant ist das
allerdings nicht. Besser wäre es, bei großen Arrays seinen eigenen
Quicksort zu schreiben (s. z.B: Sedgewick, Algorithms in C) für obiges
Beispiel dürfte der Aufwand jedoch nicht lohnen.

<?php
function my_sort($data, $level, $order="asc") {

  $temp = array();
  $new = array();

  reset($data);
  $anz = count($data);

  # Spalte isolieren
  while (list($k, $v)=each($data))
    if ($level == 0) {
	  $temp[$k]=$k;
	} else {
	  reset($v);
	  $max = $level-1;
	  if ($max<count($v)) {
	    for ($j=0; $j<$max; $j++)
		  next($v);
	    list(, $v)=each($v);
	    $temp[$k]=$v;
	  }
	}

  # Sortierung
  if ("asc"==$order)
    asort($temp);
  else
    arsort($temp);

  # Kopieren
  reset($temp);
  while (list($k,)=each($temp))
    $new[]=array($k, $data[$k]);

  return $new;
}

function show_array($data, $level=0) {

  reset($data);
  while (list($k, $v)=each($data)) {
    if (is_array($v))
	  $level=show_array($v, ++$level, $txt);
	else
      echo "$v ";
  }

  $level--;
  if (0==$level)
    echo "\n";
  return $level;
}

$data["eins"] = array (4, 8, 12);
$data["zwei"] = array (5, 7, 11);
$data["drei"] = array (13, 2, 15);

$new = my_sort($data, 3, "asc");
show_array($new);
?>

Auf die schnelle nicht gesehen habe ich eine Lösung bei der auch die
Struktur erhalten bleibt. Das Snippelt wandelt sie leicht um. Vielleicht
magst Du ja die notwendige Verbesserung posten.

Ulf


php::bar PHP Wiki   -   Listenarchive