Sortieren Sie ein Array assoziativer Arrays nach Spaltenwert

Lesezeit: 8 Minuten

Matts Benutzeravatar
Matt

Angesichts dieses Arrays:

$inventory = array(

   array("type"=>"fruit", "price"=>3.50),
   array("type"=>"milk", "price"=>2.90),
   array("type"=>"pork", "price"=>5.43),

);

Ich möchte sortieren $inventory‘s-Elemente nach Preis erhalten:

$inventory = array(

   array("type"=>"pork", "price"=>5.43),
   array("type"=>"fruit", "price"=>3.50),
   array("type"=>"milk", "price"=>2.90),

);

Wie kann ich das machen?

  • mögliches Duplikat von How do I sort a multidimensional array in php

    – Jon

    26. Juli 2013 um 9:33 Uhr

  • Warum strukturieren Sie Ihr Eingabearray nicht einfach so um, dass die price Spalte kommt zuerst und type kommt an zweiter Stelle? So können Sie einfach anrufen rsort(). 3v4l.org/2meqs

    – mickmackusa

    15. April 2021 um 8:48 Uhr

  • Kanonisch sortieren

    – mickmackusa

    13. Mai 2022 um 11:40 Uhr

Benutzeravatar von Josh Davis
Josh Davis

Du hast recht, die gesuchte Funktion ist array_multisort().

Hier ist ein Beispiel, das direkt aus dem Handbuch entnommen und an Ihren Fall angepasst wurde:

$price = array();
foreach ($inventory as $key => $row)
{
    $price[$key] = $row['price'];
}
array_multisort($price, SORT_DESC, $inventory);

Ab PHP 5.5.0 können Sie verwenden array_column() statt dessen foreach:

$price = array_column($inventory, 'price');

array_multisort($price, SORT_DESC, $inventory);

  • Dies ist jedoch definitiv teurer als die Alternativen.

    – Matt

    22. Oktober 2009 um 0:39 Uhr

  • Teurer? Das ist seltsam, auf meinem Rechner (auf dem PHP 5.3.1-dev läuft) ist array_multisort() bei kleinen Arrays ein paar Prozent schneller und bei großen Arrays (100+ Elemente) bis zu 100-mal schneller.

    – Josh Davis

    22. Oktober 2009 um 2:49 Uhr

  • Es sollte keine Änderung erfordern, um mit numerischen Tasten zu arbeiten. Wenn Sie auf einen Fehler oder ein seltsames Verhalten im Zusammenhang mit Zifferntasten stoßen, posten Sie es als neue Frage.

    – Josh Davis

    5. Januar 2012 um 0:22 Uhr

  • array_multisort hat ein großes Problem: Es behält den ursprünglichen Schlüssel nicht bei.

    – Maschinensüchtig

    27. September 2013 um 7:04 Uhr

  • @machineaddict behält die assoziativen Schlüssel bei.

    – Matej Svajger

    23. April 2015 um 19:54 Uhr

Benutzeravatar von Mark Amery
Markus Amery

PHP7+

Ab PHP 7 kann dies prägnant mit erfolgen usort mit einem Anonyme Funktion das nutzt die Raumschiffbetreiber Elemente zu vergleichen.

Sie können eine aufsteigende Sortierung wie folgt durchführen:

usort($inventory, function ($item1, $item2) {
    return $item1['price'] <=> $item2['price'];
});

Oder eine absteigende Sortierung wie folgt:

usort($inventory, function ($item1, $item2) {
    return $item2['price'] <=> $item1['price'];
});

Beachten Sie Folgendes, um zu verstehen, wie dies funktioniert usort nimmt eine vom Benutzer bereitgestellte Vergleichsfunktion, die sich wie folgt verhalten muss (aus den Dokumenten):

Die Vergleichsfunktion muss eine Ganzzahl kleiner, gleich oder größer als Null zurückgeben, wenn das erste Argument als kleiner, gleich oder größer als das zweite betrachtet wird.

Und beachte auch das <=>der Raumschiffbetreiber,

gibt 0 zurück, wenn beide Operanden gleich sind, 1, wenn der linke größer ist, und -1, wenn der rechte größer ist

das ist genau was usort braucht. Tatsächlich ist fast die gesamte Begründung für das Hinzufügen gegeben <=> zur Sprache in https://wiki.php.net/rfc/combined-comparison-operator ist es das

macht schreibende Rückrufe zur Verwendung mit bestellen usort() Einfacher


PHP5.3+

PHP 5.3 hat anonyme Funktionen eingeführt, hat aber noch keinen Spaceship-Operator. Können wir noch verwenden usort um unser Array zu sortieren, aber es ist etwas ausführlicher und schwerer zu verstehen:

usort($inventory, function ($item1, $item2) {
    if ($item1['price'] == $item2['price']) return 0;
    return $item1['price'] < $item2['price'] ? -1 : 1;
});

Beachten Sie, dass Komparatoren, die sich mit ganzzahligen Werten befassen, ziemlich häufig nur die Differenz der Werte zurückgeben, z $item2['price'] - $item1['price']Wir kippen tun Sie das in diesem Fall sicher. Dies liegt daran, dass die Preise im Beispiel des Fragestellers Gleitkommazahlen sind, aber die Vergleichsfunktion, an die wir übergeben usort muss ganze Zahlen zurückgeben für usort richtig arbeiten:

Rückkehr nicht ganzzahlig Werte aus der Vergleichsfunktion, z. B. Float, führen zu einer internen Umwandlung des Rückgabewerts des Callbacks in eine ganze Zahl. Werte wie 0,99 und 0,1 werden also beide in einen ganzzahligen Wert von 0 umgewandelt, wodurch solche Werte als gleich verglichen werden.

Dies ist eine wichtige Falle, die Sie bei der Verwendung beachten sollten usort in PHP 5.x! Meine ursprüngliche Version dieser Antwort hat diesen Fehler gemacht, und dennoch habe ich zehn Upvotes über Tausende von Aufrufen gesammelt, anscheinend ohne dass jemand den schwerwiegenden Fehler bemerkt hat. Die Leichtigkeit, mit der Dummköpfe wie ich Vergleichsfunktionen vermasseln können, ist genau der Grund dafür, dass der einfacher zu verwendende Raumschiff-Operator in PHP 7 zur Sprache hinzugefügt wurde.

  • Tut mir leid, aber dieser Ansatz löscht die Zeichenfolgenschlüssel aus assoziativen Arrays. Stattdessen sollte die Funktion “uasort” verwendet werden.

    – Matteo-SoftNet

    26. März 2014 um 11:54 Uhr


  • @DotMat Interessant – davon wusste ich nichts uasort. Nach einem Blick in die Dokumentation ist diese Antwort jedoch immer noch richtig in diesem Fall. Im Beispiel des OP hat das zu sortierende Array sequenzielle numerische Indizes anstelle von Zeichenfolgenindizes usort ist angemessener. Verwenden uasort auf einem sequentiell indizierten Array führt zu einem sortierten Array, das nicht nach seinen numerischen Indizes geordnet ist, sodass das erste Element, das in a gesehen wird foreach Schleife ist nicht $your_array[0]was wahrscheinlich kein wünschenswertes Verhalten ist.

    – Mark Amery

    26. März 2014 um 12:47 Uhr


  • Für Infos, mit numerischen Schlüsseln (die Artikel-IDs sind), die aus einer JSON-Datei extrahiert wurden, und PHP 8x habe ich uasort und das Raumschiff verwendet, um den Schlüsselwert nicht zu ändern (der Wert bleibt also bei der ID des ursprünglichen Artikels). Sehen php.net/manual/en/array.sorting.php um herauszufinden, wer es braucht, welche Tastenkombination pflegt. Danke für diese Antwort, die wirklich hilfreich war.

    – G-Cyrillus

    7. Januar um 22:15 Uhr

Benutzeravatar von Mariano Iglesias
Mariano Iglesias

Während andere die Verwendung von korrekt vorgeschlagen haben array_multisort()aus irgendeinem Grund scheint keine Antwort die Existenz anzuerkennen array_column(), was die Lösung erheblich vereinfachen kann. Also mein Vorschlag wäre:

array_multisort(array_column($inventory, 'price'), SORT_DESC, $inventory);

Falls Sie es wollen Sortierung ohne Berücksichtigung der Groß-/Kleinschreibung auf Saiten können Sie verwenden SORT_NATURAL|SORT_FLAG_CASE

array_multisort(array_column($inventory, 'key_name'), SORT_DESC, SORT_NATURAL|SORT_FLAG_CASE, $inventory);

  • Aus irgendeinem Grund konnte ich es nicht mit Zeichenfolgen mit Klein-/Großbuchstaben zum Laufen bringen. Sogar mit dem SORT_FLAG_CASE. Folgendes hat für mich für den String-Vergleich funktioniert: array_multisort( array_map(strtolower, array_column($ipr_projects, ‘Name’)), SORT_ASC, $ipr_projects);

    – Pabamato

    19. April 2018 um 22:36 Uhr


  • Funktioniert gut PHP 7.4

    – Bang Nguyen

    4. Juli 2022 um 8:34 Uhr

Da Ihre Array-Elemente selbst Arrays mit Zeichenfolgenschlüsseln sind, ist es am besten, eine benutzerdefinierte Vergleichsfunktion zu definieren. Es ist ziemlich schnell und einfach zu tun. Versuche dies:

function invenDescSort($item1,$item2)
{
    if ($item1['price'] == $item2['price']) return 0;
    return ($item1['price'] < $item2['price']) ? 1 : -1;
}
usort($inventory,'invenDescSort');
print_r($inventory);

Erzeugt Folgendes:

Array
(
    [0] => Array
        (
            [type] => pork
            [price] => 5.43
        )

    [1] => Array
        (
            [type] => fruit
            [price] => 3.5
        )

    [2] => Array
        (
            [type] => milk
            [price] => 2.9
        )

)

Benutzeravatar von Danielzt
Danielzt

Ich endete damit:

function sort_array_of_array(&$array, $subfield)
{
    $sortarray = array();
    foreach ($array as $key => $row)
    {
        $sortarray[$key] = $row[$subfield];
    }

    array_multisort($sortarray, SORT_ASC, $array);
}

Rufen Sie einfach die Funktion auf und übergeben Sie das Array und den Namen des Felds des Arrays der zweiten Ebene. Wie:

sort_array_of_array($inventory, 'price');

  • @MarkAmery Ich bevorzuge Antworten, die in Funktionen enthalten sind. Es ermutigt Copy-Paster, Funktionen zu verwenden und hoffentlich weniger Spaghetti-Code zu schreiben.

    – Gans

    1. Juni 2017 um 23:53 Uhr

Benutzeravatar von kenorb
kenorb

Sie können verwenden usort mit Anonymfunktion, z

usort($inventory, function ($a, $b) { return strnatcmp($a['price'], $b['price']); });

  • @MarkAmery Ich bevorzuge Antworten, die in Funktionen enthalten sind. Es ermutigt Copy-Paster, Funktionen zu verwenden und hoffentlich weniger Spaghetti-Code zu schreiben.

    – Gans

    1. Juni 2017 um 23:53 Uhr

Aus Sortieren Sie ein Array assoziativer Arrays nach dem Wert des angegebenen Schlüssels in PHP:

mit usort (http://php.net/usort) können wir ein Array in aufsteigender und absteigender Reihenfolge sortieren. Wir müssen nur eine Funktion erstellen und sie als Parameter in usort übergeben. Wie im folgenden Beispiel wird größer als für aufsteigende Reihenfolge verwendet, wenn wir die Bedingung kleiner als übergeben haben, wird sie in absteigender Reihenfolge sortiert. Beispiel :

$array = array(
  array('price'=>'1000.50','product'=>'test1'),
  array('price'=>'8800.50','product'=>'test2'),
  array('price'=>'200.0','product'=>'test3')
);

function cmp($a, $b) {
  return $a['price'] > $b['price'];
}

usort($array, "cmp");
print_r($array);

Ausgang:

Array
 (
    [0] => Array
        (
            [price] => 200.0
            [product] => test3
        )

    [1] => Array
        (
            [price] => 1000.50
            [product] => test1
        )

    [2] => Array
        (
            [price] => 8800.50
            [product] => test2
        )
  )

  • Diese Antwort tauchte in der Warteschlange für Überprüfungen mit geringer Qualität auf, vermutlich weil Sie den Code nicht erklären. Wenn dieser Code die Frage beantwortet, sollten Sie erwägen, etwas Text hinzuzufügen, der den Code in Ihrer Antwort erklärt. Auf diese Weise ist es viel wahrscheinlicher, dass Sie mehr Upvotes erhalten – und dem Fragesteller helfen, etwas Neues zu lernen.

    – lmo

    30. August 2016 um 23:00 Uhr

  • -1; Die cmp Funktion ist hier falsch. Es soll zurückkehren “eine ganze Zahl kleiner, gleich oder größer als Null, wenn das erste Argument als kleiner, gleich oder größer als das zweite betrachtet wird” sondern kehrt zurück true oder false. Es scheint bemerkenswerterweise trotzdem zu funktionieren – vielleicht auch wegen der aktuellen Umsetzung usort and friends behandelt die Fälle “weniger als” und “gleich” identisch – aber verlassen Sie sich nicht darauf, dass es in zukünftigen PHP-Versionen weiter funktioniert. Wenn sie versuchen, Sortierungen stabil zu machen (dh sich nicht unnötig um gleiche Elemente zu bewegen), wird dies brechen.

    – Mark Amery

    29. Juni 2019 um 15:18 Uhr

  • Auch, usort wäre passender als uasort hier, da uasort behält die Zuordnung zwischen Schlüsseln und Werten bei, was verwirrend und unerwartet ist, wenn man mit einem sequentiellen numerischen Array arbeitet. Zum Beispiel die Indizes von $array oben nach dem Anruf uasort sind 2, 0 und 1, in dieser Reihenfolge. Wenn Sie das nicht aus irgendeinem Grund möchten, werden Sie sich wahrscheinlich wohler fühlen usortwodurch das Array neu indiziert und neu geordnet wird.

    – Mark Amery

    29. Juni 2019 um 15:20 Uhr


  • in php7+: in der cmp-Funktion sollte man den <=> ‘spaceship’-Operator verwenden

    – druganow

    9. Oktober 2020 um 12:27 Uhr

1445200cookie-checkSortieren Sie ein Array assoziativer Arrays nach Spaltenwert

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy