Benutzerdefinierte Schlüsselsortierung eines flachen Assoziativs basierend auf einem anderen Array

Lesezeit: 6 Minuten

Benutzeravatar von alex
Alex

Ist es in PHP möglich, so etwas zu tun? Wie würden Sie vorgehen, um eine Funktion zu schreiben? Hier ist ein Beispiel. Die Reihenfolge ist das Wichtigste.

$customer['address'] = '123 fake st';
$customer['name'] = 'Tim';
$customer['dob'] = '12/08/1986';
$customer['dontSortMe'] = 'this value doesnt need to be sorted';

Und ich würde gerne sowas machen

$properOrderedArray = sortArrayByArray($customer, array('name', 'dob', 'address'));

Weil ich am Ende ein foreach() verwende und sie nicht in der richtigen Reihenfolge sind (weil ich die Werte an eine Zeichenfolge anhänge, die in der richtigen Reihenfolge sein muss, und ich nicht alle Array-Schlüssel im Voraus kenne / Werte).

Ich habe die internen Array-Funktionen von PHP durchgesehen, aber es scheint, dass Sie nur alphabetisch oder numerisch sortieren können.

Benutzeravatar von Darkwaltz4
Dunkelwalzer4

Benutz einfach array_merge oder array_replace. array_merge funktioniert, indem Sie mit dem Array beginnen, das Sie ihm geben (in der richtigen Reihenfolge) und die Schlüssel mit Daten aus Ihrem tatsächlichen Array überschreiben/hinzufügen:

$customer['address']    = '123 fake st';
$customer['name']       = 'Tim';
$customer['dob']        = '12/08/1986';
$customer['dontSortMe'] = 'this value doesnt need to be sorted';

$properOrderedArray = array_merge(array_flip(array('name', 'dob', 'address')), $customer);
// or
$properOrderedArray = array_replace(array_flip(array('name', 'dob', 'address')), $customer);

// $properOrderedArray: array(
//   'name'       => 'Tim',
//   'dob'        => '12/08/1986',
//   'address'    => '123 fake st',
//   'dontSortMe' => 'this value doesnt need to be sorted')

PS: Ich beantworte diese “abgestandene” Frage, weil ich denke, dass alle Schleifen, die als vorherige Antworten gegeben wurden, übertrieben sind.

  • Es funktioniert gut, wenn Sie Zeichenfolgenschlüssel haben, aber nicht für die numerischen. PHP Docs: „Wenn die Eingabe-Arrays die gleichen String-Schlüssel haben, dann überschreibt der spätere Wert für diesen Schlüssel den vorherigen. Wenn die Arrays jedoch numerische Schlüssel enthalten, wird der spätere Wert den ursprünglichen Wert nicht überschreiben, wird es aber angehängt.”

    – bolbol

    7. November 2012 um 6:52 Uhr


  • Schön, aber was ist, wenn die Schlüssel nicht in den Werten vorhanden sind? Ich brauche das, aber nur, wenn einer der Schlüssel existiert … Brauche dann wahrscheinlich einen Foreach darauf …

    – Solomon Closson

    8. Mai 2014 um 22:49 Uhr

  • In meinem Fall ist es array_replace anstelle von array_merge. array_merge kombiniert beide Werte, anstatt das zweite Array durch die geordneten Schlüssel zu ersetzen.

    – neofreko

    12. November 2014 um 6:26 Uhr

  • Ich bin vor ein paar Jahren auf der Suche nach etwas anderem auf Ihre Lösung gestoßen – und dachte mir, das ist im Vergleich zu den Schleifen äußerst effizient. Jetzt brauche ich Ihre Lösung und ich habe eine Stunde lang gesucht, um sie wieder zu finden! Danke!

    – Michael

    13. November 2017 um 3:29 Uhr

  • Wenn das Array ‘order’ (dh array(‘name’, ‘dob’, ‘address’)) mehr Schlüssel als das zu sortierende Array hat, würde zusätzlich array_intersect des resultierenden sortierten Arrays mit dem ursprünglichen Array abgeschnitten streunende Schlüssel, die bei array_merge hinzugefügt wurden.

    – bbe

    8. Januar 2018 um 10:24 Uhr


Benutzeravatar von Eran Galperin
Eran Galperin

Los geht’s:

function sortArrayByArray(array $array, array $orderArray) {
    $ordered = array();
    foreach ($orderArray as $key) {
        if (array_key_exists($key, $array)) {
            $ordered[$key] = $array[$key];
            unset($array[$key]);
        }
    }
    return $ordered + $array;
}

  • Sie können also 2 Arrays mit einem +-Zeichen verbinden? Ich wusste nie, dass ich verwendet habe array_merge()!

    – Alex

    24. September 2009 um 23:08 Uhr

  • Ist das besser als mit usort() oder uasort()?

    – Grantwparks

    25. September 2009 um 19:57 Uhr

  • Sie sollten ein einfügen break Anweisung, sobald der Wert gefunden wurde.

    – Adel

    26. September 2011 um 14:50 Uhr


  • @alex Seien Sie sehr vorsichtig, wenn Sie ersetzen array_merge() mit dem Array + Operator. Es fügt per Taste (auch für numerische Tasten) und von zusammen links nach rechtswährend array_merge verschmilzt aus rechts nach links und überschreibt niemals numerische Tasten. Z.B [0,1,2]+[0,5,6,7] = [0,1,2,7] während array_merge([0,1,2],[0,5,6,7]) = [0,1,2,0,5,6,7] Und ['a' => 5] + ['a' => 7] = ['a' => 5] Aber array_merge(['a' => 5], ['a' => 7]) = ['a' => 7].

    – Grippe

    5. August 2015 um 8:07 Uhr

  • Der + oder Vereinigungsoperator ist gemäß vollkommen gültig PHP-Dokumentation In einigen Anwendungsfällen ist es genau das, was Sie wollen, wenn Sie die Zifferntasten beibehalten müssen.

    – Hexodos

    12. Mai 2017 um 21:14 Uhr

Wie wäre es mit dieser Lösung

$order = array(1,5,2,4,3,6);

$array = array(
    1 => 'one',
    2 => 'two',
    3 => 'three',
    4 => 'four',
    5 => 'five',
    6 => 'six'
);

uksort($array, function($key1, $key2) use ($order) {
    return (array_search($key1, $order) > array_search($key2, $order));
});

  • Das ist nicht sehr effizient. Für jeden Vergleich werden zwei lineare Suchen im Array durchgeführt. Nehmen wir an, die Zeitkomplexität von uksort() sei O(n * log n)dann läuft dieser Algorithmus ein O(n^2 * log(n)).

    – Der Betreiber

    23. Januar 2020 um 9:12 Uhr

  • Diese Lösungen funktionieren ziemlich gut für Arrays, denen ein Wert in der Sortierreihenfolge fehlt. Für kleine Arrays ist die Komplexität wahrscheinlich vernachlässigbar. Die Lösungen mit mehreren Array-Funktionen könnten sogar noch schlechter sein.

    – 2. Kauboy

    27. Juli 2021 um 15:56 Uhr

  • Nur array_flip die $order davor useund es geht schneller

    – V. Volkov

    6. August 2022 um 6:59 Uhr

  • @V.Volkov Aber in diesem Fall erhalten Sie ein falsches Ergebnis

    – Peter de Groot

    7. August 2022 um 7:13 Uhr

  • @PeterdeGroot Entschuldigung, dass ich es nicht klargestellt habe 🙂 $order = array_flip( $order ); Vor dem uksort Und return $order[ $key1 ] > $order[ $key2 ]; innen uksort

    – V. Volkov

    7. August 2022 um 7:47 Uhr

Ein anderer Weg für PHP >= 5.3.0:

$customer['address'] = '123 fake st';
$customer['name'] = 'Tim';
$customer['dob'] = '12/08/1986';
$customer['dontSortMe'] = 'this value doesnt need to be sorted';

$customerSorted = array_replace(array_flip(array('name', 'dob', 'address')), $customer);

Ergebnis:

Array (
  [name] => Tim
  [dob] => 12/08/1986
  [address] => 123 fake st
  [dontSortMe] => this value doesnt need to be sorted
)

Funktioniert gut mit Zeichenfolgen und numerischen Tasten.

function sortArrayByArray(array $toSort, array $sortByValuesAsKeys)
{
    $commonKeysInOrder = array_intersect_key(array_flip($sortByValuesAsKeys), $toSort);
    $commonKeysWithValue = array_intersect_key($toSort, $commonKeysInOrder);
    $sorted = array_merge($commonKeysInOrder, $commonKeysWithValue);
    return $sorted;
}

Benutzeravatar von Stephan Vierkant
Stefan Vierkant

Ich habe die Lösung von Darkwaltz4 verwendet, aber verwendet array_fill_keys anstatt array_flipzu füllen NULL wenn kein Schlüssel gesteckt ist $array.

$properOrderedArray = array_replace(array_fill_keys($keys, null), $array);

Benutzeravatar von hakre
hakre

Nehmen Sie ein Array als Ihre Bestellung:

$order = array('north', 'east', 'south', 'west');

Sie können ein anderes Array basierend auf Werten mit sortieren array_intersectDokumente:

/* sort by value: */
$array = array('south', 'west', 'north');
$sorted = array_intersect($order, $array);
print_r($sorted);

Oder verwenden Sie in Ihrem Fall zum Sortieren nach Schlüsseln array_intersect_keyDokumente:

/* sort by key: */
$array = array_flip($array);
$sorted = array_intersect_key(array_flip($order), $array);
print_r($sorted);

Beide Funktionen behalten die Reihenfolge des ersten Parameters bei und geben nur die Werte (oder Schlüssel) aus dem zweiten Array zurück.

Für diese beiden Standardfälle müssen Sie also keine eigene Funktion schreiben, um das Sortieren/Neuanordnen durchzuführen.

  • Der Schnittpunkt würde die Einträge entfernen, die er nicht im Voraus kennt.

    – DanMan

    6. März 2013 um 15:02 Uhr

  • Dies ist für die Sortierung nach Schlüsseln falsch. array_intersect_key gibt nur die Werte von array1 zurück, nicht von array2

    – gespenstisch

    21. Januar 2015 um 14:30 Uhr

  • Vereinbart mit pavsid – das Beispiel array_intersect_key ist falsch – es gibt die Werte aus dem ersten Array zurück, nicht aus dem zweiten.

    – Jonathan Aquino

    15. April 2015 um 3:18 Uhr

1445150cookie-checkBenutzerdefinierte Schlüsselsortierung eines flachen Assoziativs basierend auf einem anderen Array

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

Privacy policy