Code:
function search($array, $key, $value)
{
$results = array();
if (is_array($array)) {
if (isset($array[$key]) && $array[$key] == $value) {
$results[] = $array;
}
foreach ($array as $subarray) {
$results = array_merge($results, search($subarray, $key, $value));
}
}
return $results;
}
$arr = array(0 => array(id=>1,name=>"cat 1"),
1 => array(id=>2,name=>"cat 2"),
2 => array(id=>3,name=>"cat 1"));
print_r(search($arr, 'name', 'cat 1'));
Ausgabe:
Array
(
[0] => Array
(
[id] => 1
[name] => cat 1
)
[1] => Array
(
[id] => 3
[name] => cat 1
)
)
Wenn Effizienz wichtig ist, können Sie sie so schreiben, dass alle rekursiven Aufrufe ihre Ergebnisse in demselben temporären $results
Array speichern, anstatt Arrays wie folgt zusammenzuführen:
function search($array, $key, $value)
{
$results = array();
search_r($array, $key, $value, $results);
return $results;
}
function search_r($array, $key, $value, &$results)
{
if (!is_array($array)) {
return;
}
if (isset($array[$key]) && $array[$key] == $value) {
$results[] = $array;
}
foreach ($array as $subarray) {
search_r($subarray, $key, $value, $results);
}
}
Der Schlüssel dort ist, dass search_r
sein vierter Parameter eher als Referenz als als Wert verwendet wird. Das kaufmännische Und &
ist entscheidend.
Zu Ihrer Information: Wenn Sie eine ältere Version von PHP haben, müssen Sie den Referenzteil im Aufruf an search_r
und nicht in seiner Deklaration angeben . Das heißt, die letzte Zeile wird search_r($subarray, $key, $value, &$results)
.
$key
nicht ausgegeben, wenn er nicht im Array vorhanden ist? Wäre es nicht besser zu tunif (array_key_exists($key, $array) && $array[$key] == $value) {
?$value
das istnull
und die Funktion funktioniert nicht ...array empty
... Wie ein Array zu haben , auch wenn$value
=null
? wiesearch($array, 'id', null)
?Wie wäre es stattdessen mit der SPL- Version? Das erspart Ihnen das Tippen:
Was großartig ist, ist, dass im Grunde derselbe Code für Sie durch ein Verzeichnis iteriert, indem ein RecursiveDirectoryIterator anstelle eines RecursiveArrayIterator verwendet wird. SPL ist der Roxor.
Das einzige Problem bei SPL ist, dass es im Web schlecht dokumentiert ist. Einige PHP-Bücher enthalten jedoch einige nützliche Details, insbesondere Pro PHP. und Sie können wahrscheinlich auch für weitere Informationen googeln.
quelle
Ref: http://php.net/manual/en/function.array-filter.php
quelle
Kam zurück, um dieses Update für alle zu veröffentlichen, die einen Optimierungstipp für diese Antworten benötigen, insbesondere John Kugelmans großartige Antwort oben.
Seine gepostete Funktion funktioniert einwandfrei, aber ich musste dieses Szenario für die Verarbeitung einer Ergebnismenge mit 12.000 Zeilen optimieren. Die Funktion brauchte ewige 8 Sekunden, um alle Aufzeichnungen durchzugehen, waaaaaay zu lange.
Ich brauchte einfach die Funktion, um die Suche zu stoppen und zurückzukehren, wenn eine Übereinstimmung gefunden wurde. Wenn wir also nach einer Kunden-ID suchen, wissen wir, dass wir nur eine in der Ergebnismenge haben, und sobald wir die Kunden-ID im mehrdimensionalen Array gefunden haben, möchten wir zurückkehren.
Hier ist die geschwindigkeitsoptimierte (und stark vereinfachte) Version dieser Funktion für alle Bedürftigen. Im Gegensatz zu anderen Versionen kann es nur eine Array-Tiefe verarbeiten, rekursiert nicht und macht das Zusammenführen mehrerer Ergebnisse überflüssig.
Dies brachte die Aufgabe, die 12 000 Datensätze auf 1,5 Sekunden abzugleichen, zum Erliegen. Immer noch sehr teuer, aber viel vernünftiger.
quelle
Eine kleine Verbesserung der schnellen Version.
quelle
Achten Sie auf lineare Suchalgorithmen (die oben genannten sind linear) in mehrdimensionalen Arrays, da diese die Komplexität erhöhen, da ihre Tiefe die Anzahl der Iterationen erhöht, die zum Durchlaufen des gesamten Arrays erforderlich sind. Z.B:
würde höchstens 200 Iterationen benötigen, um mit einem geeigneten Algorithmus zu finden, wonach Sie suchen (wenn die Nadel bei [100] [1] wäre).
Lineare Algorithmen arbeiten in diesem Fall bei O (n) (Reihenfolge der Gesamtzahl der Elemente im gesamten Array). Dies ist schlecht. Eine Million Einträge (z. B. ein Array von 1000 x 100 x 10) würden durchschnittlich 500.000 Iterationen benötigen, um die Nadel zu finden. Was würde auch passieren, wenn Sie die Struktur Ihres mehrdimensionalen Arrays ändern würden? Und PHP würde einen rekursiven Algorithmus starten, wenn Ihre Tiefe mehr als 100 wäre. Informatik kann es besser machen:
Verwenden Sie nach Möglichkeit immer Objekte anstelle mehrdimensionaler Arrays:
und wenden Sie eine benutzerdefinierte Komparatorschnittstelle und -funktion an, um sie zu sortieren und zu finden:
Sie können
uasort()
einen benutzerdefinierten Komparator verwenden. Wenn Sie sich abenteuerlustig fühlen, sollten Sie Ihre eigenen Sammlungen für Ihre Objekte implementieren, die sie sortieren und verwalten können (ich erweitere ArrayObject immer um mindestens eine Suchfunktion).Sobald sie sortiert sind (uasort ist O (n log n), was so gut ist, wie es über beliebige Daten geht), kann die binäre Suche die Operation in O (log n) -Zeit ausführen, dh eine Million Einträge dauert nur ~ 20 Iterationen Suche. Soweit mir bekannt ist, ist die benutzerdefinierte Komparator-Binärsuche in PHP nicht implementiert (
array_search()
verwendet eine natürliche Reihenfolge, die auf Objektreferenzen und nicht auf deren Eigenschaften funktioniert). Sie müssten dies selbst implementieren, wie ich es tue.Dieser Ansatz ist effizienter (es gibt keine Tiefe mehr) und vor allem universell (vorausgesetzt, Sie erzwingen die Vergleichbarkeit mithilfe von Schnittstellen), da Objekte definieren, wie sie sortiert werden, sodass Sie den Code unbegrenzt recyceln können. Viel besser =)
quelle
Hier ist die Lösung:
quelle
quelle
http://snipplr.com/view/51108/nested-array-search-by-value-or-key/
quelle
quelle
Ich brauchte etwas Ähnliches, aber um nach mehrdimensionalen Arrays nach Wert zu suchen ... Ich nahm Johns Beispiel und schrieb
Ich hoffe es hilft jemandem :)
quelle
Dies ist eine überarbeitete Funktion von der, die John K. gepostet hat ... Ich muss nur den spezifischen Schlüssel im Array und nichts darüber greifen.
quelle
Und eine andere Version, die den Schlüsselwert von dem Array-Element zurückgibt, in dem sich der Wert befindet (keine Rekursion, optimiert für Geschwindigkeit):
Vielen Dank an alle, die hier gepostet haben.
quelle
quelle
Wenn Sie nach einer Reihe von Schlüsseln suchen möchten, ist dies gut
Schlüssel werden nicht überschrieben, da sich jeder Satz von Schlüssel => -Werten in einem separaten Array im resultierenden Array befindet.
Wenn Sie keine doppelten Schlüssel möchten, verwenden Sie diesen
quelle