Mehrdimensionale PHP-Array-Suche nach Wert


331

Ich habe ein Array, in dem ich suchen möchte uid und den Schlüssel des Arrays erhalten .

Beispiele

Angenommen, wir haben das folgende zweidimensionale Array:

$userdb = array(
    array(
        'uid' => '100',
        'name' => 'Sandra Shush',
        'pic_square' => 'urlof100'
    ),
    array(
        'uid' => '5465',
        'name' => 'Stefanie Mcmohn',
        'pic_square' => 'urlof100'
    ),
    array(
        'uid' => '40489',
        'name' => 'Michael',
        'pic_square' => 'urlof40489'
    )
);

Der Funktionsaufruf search_by_uid(100)(UID des ersten Benutzers) sollte zurückkehren 0.

Der Funktionsaufruf search_by_uid(40489)sollte zurückkehren 2.

Ich habe versucht, Schleifen zu erstellen, möchte aber einen Code, der schneller ausgeführt wird.


Interessanterweise fügen die Unterstrich- (und Lowdash-) Bibliotheken diese Funktion zu Javascript hinzu ...
ErichBSchulz

9
Ich habe ein Skript geschrieben, um die Leistung einiger Antworten zu testen. Es generiert ein Array von Arrays mit 500.000 Elementen und durchsucht es nach einem Wert im letzten Element. Ich habe eine Funktion wie die akzeptierte Antwort mit den beiden array_columnEinzeiler-Antworten verglichen . Ich habe sie alle geändert, um das tatsächlich erkannte Array zurückzugeben, nicht nur den Schlüssel, da dies normalerweise mein Anwendungsfall ist. Die Funktionsmethode erzielte für jede Methode eine durchschnittliche Mikroverzögerung von 0,361, Suchspalte 0,184 und Schlüsselspalte 0,189 über 1000 Läufe.
Josh

Antworten:


474
function searchForId($id, $array) {
   foreach ($array as $key => $val) {
       if ($val['uid'] === $id) {
           return $key;
       }
   }
   return null;
}

Das wird funktionieren. Sie sollten es so nennen:

$id = searchForId('100', $userdb);

Es ist wichtig zu wissen, dass, wenn Sie vom ===Operator verglichene Typen verwenden, diese exakt gleich sein müssen. In diesem Beispiel müssen Sie suchen stringoder ==stattdessen nur verwenden ===.

Basierend auf Angoru Antwort. In späteren Versionen von PHP ( >= 5.5.0) können Sie Einzeiler verwenden.

$key = array_search('100', array_column($userdb, 'uid'));

Hier ist die Dokumentation: http://php.net/manual/en/function.array-column.php .


8
Sie sollten dies auch ohne PHP 5.5 in einem Einzeiler tun können, indem Sie array_map anstelle von array_column verwenden. Ersetzen Sie einfach array_column($userdb, 'uid')mitarray_map(function($v){return $v['uid'];},$userdb)
Jesse Green

1
Ja, du hast recht. Lambda-Funktionen sind seit PHP 5.3 verfügbar. und besser ist array_searches nicht?
Jakub Truneček

@angoru Ich denke, die ursprüngliche Lösung (die foreachSchleife) wird schneller ausgeführt, da sie stoppt, sobald eine Übereinstimmung gefunden wird. Die neuere Lösung muss das gesamte Array einmal array_columndurchlaufen, um es zu extrahieren , und es dann ein zweites Mal durchlaufen, um die Suche durchzuführen (bis eine Übereinstimmung gefunden wird). Die neuere Lösung ist leichter zu lesen, prägnanter, aber das OP hat speziell die Leistung als Problem
angesprochen

@ JakubTruneček. Ich habe etwas mit dem gleichen Array zu tun, das in der Frage angegeben ist. Ich möchte den Benutzernamen aus dem Array, indem ich die ID übergebe. Die Funktion findUserName (40489) sollte 'Michael' zurückgeben. Wie ist es möglich?
Ashok Gujjar

@ JakubTruneček Hallo, ich habe dieses Problem in meinem Code gesehen, aber ich habe eine ganz andere Sache. In meinem Fall ist der 'uid'-Wert mehrmals vorhanden, daher muss ich ein Array mit dem gefundenen Schlüssel erhalten.
Bhavin Thummar

314

Wenn Sie (PHP 5> = 5.5.0) verwenden, müssen Sie dazu keine eigene Funktion schreiben. Schreiben Sie einfach diese Zeile und fertig.

Wenn Sie nur ein Ergebnis wünschen:

$key = array_search(40489, array_column($userdb, 'uid'));

Für mehrere Ergebnisse

$keys = array_keys(array_column($userdb, 'uid'), 40489);

Falls Sie ein assoziatives Array haben, wie in den Kommentaren angegeben, können Sie es mit folgenden Elementen erstellen:

$keys = array_keys(array_combine(array_keys($userdb), array_column($userdb, 'uid')),40489);

Wenn Sie PHP <5.5.0 verwenden, können Sie diesen Backport verwenden , danke ramsey!

Update: Ich habe einige einfache Benchmarks erstellt und das Formular mit mehreren Ergebnissen scheint das schnellste zu sein, sogar schneller als die benutzerdefinierte Funktion von Jakub!


Was passiert, wenn der gesuchte Wert (in diesem Beispiel 40489) mehr als einmal angezeigt wird und ich alle angezeigten Schlüssel erhalten möchte?
Dimitris Papageorgiou

Wenn der Wert 40489 mehr als einmal im Array erscheint, gibt die Funktion ein Array von Schlüsseln zurück ... ?? @angoru
Jishan

Wenn Sie den zweiten Fall für mehrere Ergebnisse verwenden, erhalten Sie eine Reihe von Schlüsseln.
Angoru

2
Dies hat bei mir nicht funktioniert, als der Schlüssel in der $ userdb nicht als 0,1, 2 usw. gestartet wurde und der Schlüssel 1234.4566 usw. lautet. Die resultierenden Schlüssel nach der array_search sind immer 0,1,2 und so weiter am
Kaushtuv

1
Dies funktioniert nicht mit einem assoziativen Array, aber Sie können dies folgendermaßen array_search(40489, array_combine(array_keys($userdb), array_column($userdb, 'uid')))
umgehen

32

In späteren Versionen von PHP (> = 5.5.0) können Sie diesen Einzeiler verwenden:

$key = array_search('100', array_column($userdb, 'uid'));

Fügen Sie einfach array_column result in eine bestimmte Variable ein, um zu vermeiden, dass array_column für jedes Ergebnis im Array aufgerufen wird.
Maykonn

26

Aufbauend auf Jakubs hervorragender Antwort finden Sie hier eine allgemeinere Suche, mit der der Schlüssel angegeben werden kann (nicht nur für uid):

function searcharray($value, $key, $array) {
   foreach ($array as $k => $val) {
       if ($val[$key] == $value) {
           return $k;
       }
   }
   return null;
}

Verwendungszweck: $results = searcharray('searchvalue', searchkey, $array);


Dies ist sehr hilfreich. Ich habe das Gefühl, dass ich kurz davor bin, mein Problem mit dieser Lösung zu lösen, aber ich habe immer noch ein Problem. Könnten Sie vielleicht einen Einblick geben? Die Frage kann hier gefunden werden: stackoverflow.com/questions/28704644/…
jasenmp

19

Ich weiß, dass dies bereits beantwortet wurde, aber ich habe dies verwendet und es in meinem Code ein wenig erweitert, sodass Sie nicht nur nach der UID suchen mussten. Ich möchte es nur für alle anderen freigeben, die diese Funktionalität benötigen.

Hier ist mein Beispiel und bitte denken Sie daran, dass dies meine erste Antwort ist. Ich habe das Parameter-Array herausgenommen, weil ich nur ein bestimmtes Array durchsuchen musste, aber Sie konnten es leicht hinzufügen. Ich wollte im Wesentlichen nach mehr als nur der UID suchen.

In meiner Situation müssen möglicherweise mehrere Schlüssel zurückgegeben werden, wenn nach anderen Feldern gesucht wird, die möglicherweise nicht eindeutig sind.

 /**
     * @param array multidimensional 
     * @param string value to search for, ie a specific field name like name_first
     * @param string associative key to find it in, ie field_name
     * 
     * @return array keys.
     */
     function search_revisions($dataArray, $search_value, $key_to_search) {
        // This function will search the revisions for a certain value
        // related to the associative key you are looking for.
        $keys = array();
        foreach ($dataArray as $key => $cur_value) {
            if ($cur_value[$key_to_search] == $search_value) {
                $keys[] = $key;
            }
        }
        return $keys;
    }

Später schrieb ich dies, um nach einem anderen Wert und einem anderen assoziativen Schlüssel suchen zu können. In meinem ersten Beispiel können Sie also nach einem Wert in einem bestimmten assoziativen Schlüssel suchen und alle Übereinstimmungen zurückgeben.

Dieses zweite Beispiel zeigt Ihnen, wo ein Wert ('Taylor') in einem bestimmten assoziativen Schlüssel (Vorname) UND ein anderer Wert (true) in einem anderen assoziativen Schlüssel (verwendet) gefunden wird, und gibt alle Übereinstimmungen zurück (Schlüssel, bei denen Personen mit Vornamen 'Taylor' UND sind angestellt).

/**
 * @param array multidimensional 
 * @param string $search_value The value to search for, ie a specific 'Taylor'
 * @param string $key_to_search The associative key to find it in, ie first_name
 * @param string $other_matching_key The associative key to find in the matches for employed
 * @param string $other_matching_value The value to find in that matching associative key, ie true
 * 
 * @return array keys, ie all the people with the first name 'Taylor' that are employed.
 */
 function search_revisions($dataArray, $search_value, $key_to_search, $other_matching_value = null, $other_matching_key = null) {
    // This function will search the revisions for a certain value
    // related to the associative key you are looking for.
    $keys = array();
    foreach ($dataArray as $key => $cur_value) {
        if ($cur_value[$key_to_search] == $search_value) {
            if (isset($other_matching_key) && isset($other_matching_value)) {
                if ($cur_value[$other_matching_key] == $other_matching_value) {
                    $keys[] = $key;
                }
            } else {
                // I must keep in mind that some searches may have multiple
                // matches and others would not, so leave it open with no continues.
                $keys[] = $key;
            }
        }
    }
    return $keys;
}

Funktionsnutzung

$data = array(
    array(
        'cust_group' => 6,
        'price' => 13.21,
        'price_qty' => 5
    ),
    array(
        'cust_group' => 8,
        'price' => 15.25,
        'price_qty' => 4
    ),
    array(
        'cust_group' => 8,
        'price' => 12.75,
        'price_qty' => 10
    )
);

$findKey = search_revisions($data,'8', 'cust_group', '10', 'price_qty');
print_r($findKey);

Ergebnis

Array ( [0] => 2 ) 

10

Looks array_filter ist dafür eine geeignete Lösung ...

$userdb=Array
(
    (0) => Array
        (
            (uid) => '100',
            (name) => 'Sandra Shush',
            (url) => 'urlof100'
        ),

    (1) => Array
        (
            (uid) => '5465',
            (name) => 'Stefanie Mcmohn',
            (pic_square) => 'urlof100'
        ),

    (2) => Array
        (
            (uid) => '40489',
            (name) => 'Michael',
            (pic_square) => 'urlof40489'
        )
);

PHP-Code

<?php 
$search = 5465;
$found = array_filter($userdb,function($v,$k) use ($search){
  return $v['uid'] == $search;
},ARRAY_FILTER_USE_BOTH) // With latest PHP third parameter is mandatory.. Available Values:- ARRAY_FILTER_USE_BOTH OR ARRAY_FILTER_USE_KEY  

$values= print_r(array_value($found)); 
$keys =  print_r(array_keys($found)); 

@BEJAM SHIVA PRASAD Könnten Sie mir bitte mit diesem stackoverflow.com/questions/44721195/… helfen ?
Valay

zeigt einen Fehler:syntax error, unexpected '=>' (T_DOUBLE_ARROW), expecting ';'
Shihas

Können Sie bitte weitere Informationen einfügen? Ich meine, welche Zeile und Ihre Code- und Array-Struktur.
BEJGAM SHIVA PRASAD

@Shihas Ich habe die Antwort aktualisiert, ich bin sicher, dass sie gelöst wird.
BEJGAM SHIVA PRASAD

9

Ich habe eines der folgenden Beispiele für die Beschreibungsfunktion array_search geändert . Die Funktion gibt searchItemsByKeyalle Werte mit dem Schlüssel $ aus einem mehrdimensionalen Array (N Ebenen) zurück. Vielleicht wäre es für jemanden nützlich. Beispiel:

 $arr = array(
     'XXX'=>array(
               'YYY'=> array(
                    'AAA'=> array(
                          'keyN' =>'value1'
                   )
               ),
              'ZZZ'=> array(
                    'BBB'=> array(
                          'keyN' => 'value2'
                   )
               )
              //.....
           )
);


$result = searchItemsByKey($arr,'keyN');

print '<pre>';
print_r($result);
print '<pre>';
// OUTPUT
Array
(
  [0] => value1
  [1] => value2
)

Funktionscode:

function searchItemsByKey($array, $key)
{
   $results = array();

  if (is_array($array))
  {
    if (isset($array[$key]) && key($array)==$key)
        $results[] = $array[$key];

    foreach ($array as $sub_array)
        $results = array_merge($results, searchItemsByKey($sub_array, $key));
  }

 return  $results;
}

7

Hier ist ein Liner für das gleiche,

$pic_square = $userdb[array_search($uid,array_column($userdb, 'uid'))]['pic_square'];

3

Obwohl dies eine alte Frage ist und eine akzeptierte Antwort hat, dachte ich, ich würde eine Änderung der akzeptierten Antwort vorschlagen. Zunächst einmal stimme ich zu, dass die akzeptierte Antwort hier korrekt ist.

function searchArrayKeyVal($sKey, $id, $array) {
   foreach ($array as $key => $val) {
       if ($val[$sKey] == $id) {
           return $key;
       }
   }
   return false;
}

Ersetzen Sie stattdessen die voreingestellte 'uid' durch einen Parameter in der Funktion. Wenn Sie jetzt den folgenden Code aufrufen, können Sie die eine Funktion für mehrere Array-Typen verwenden. Kleine Veränderung, aber eine, die den kleinen Unterschied macht.

    // Array Data Of Users
$userdb = array (
    array ('uid' => '100','name' => 'Sandra Shush','url' => 'urlof100' ),
    array ('uid' => '5465','name' => 'Stefanie Mcmohn','url' => 'urlof100' ),
    array ('uid' => '40489','name' => 'Michael','url' => 'urlof40489' ),
);

// Obtain The Key Of The Array
$arrayKey = searchArrayKeyVal("uid", '100', $userdb);
if ($arrayKey!==false) {
    echo "Search Result: ", $userdb[$arrayKey]['name'];
} else {
    echo "Search Result can not be found";
}

PHP Fiddle Beispiel


Ein weiterer Grund, warum ich SOF benutze ... einfacher zu googeln und meinen eigenen Code oder etwas zu finden, an das ich mich erinnere. +1 für mein eigenes öffentliches Repository
Angry 84

Übrigens setzen Sie das Ergebnis auf nullund vergleichen es dann im Code mit false.
Taha Paksu

Korrigiert mit der Rückgabe von false stattdessen, aber null könnte besser sein, wenn nach Booleschen Werten gesucht wird
Angry 84

2

Ich möchte überprüfen, ob im folgenden Array $arr'abc' in Sub-Arrays vorhanden ist oder nicht

$arr = array(
    array(
        'title' => 'abc'
    )
);

Dann kann ich das benutzen

$res = array_search('abc', array_column($arr, 'title'));
if($res == ''){
    echo 'exists';
} else {
    echo 'notExists';
}

Ich denke, dies ist der einfachste Weg zu definieren


1

Ich musste eine un-Funktion verwenden, die alle Elemente in einem Array findet. Also habe ich die Funktion von Jakub Truneček wie folgt geändert:

function search_in_array_r($needle, $array) {
    $found = array();
    foreach ($array as $key => $val) {
        if ($val[1] == $needle) {
            array_push($found, $val[1]);
        }
    }
    if (count($found) != 0)
        return $found;
    else
        return null;
}

1
/**
 * searches a simple as well as multi dimension array
 * @param type $needle
 * @param type $haystack
 * @return boolean
 */
public static function in_array_multi($needle, $haystack){
    $needle = trim($needle);
    if(!is_array($haystack))
        return False;

    foreach($haystack as $key=>$value){
        if(is_array($value)){
            if(self::in_array_multi($needle, $value))
                return True;
            else
               self::in_array_multi($needle, $value);
        }
        else
        if(trim($value) === trim($needle)){//visibility fix//
            error_log("$value === $needle setting visibility to 1 hidden");
            return True;
        }
    }

    return False;
}

1

Sie können diese Funktion verwenden; https://github.com/serhatozles/ArrayAdvancedSearch

<?php 
include('ArraySearch.php');

$query = "a='Example World' and b>='2'";

$Array = array(
'a' => array('d' => '2'),
array('a' => 'Example World','b' => '2'),
array('c' => '3'), array('d' => '4'),
);

$Result = ArraySearch($Array,$query,1);

echo '<pre>';
print_r($Result);
echo '</pre>'; 

// Output:
// Array
// (
//    [0] => Array
//        (
//            [a] => Example World
//            [b] => 2
//        )
//
// )

1
$a = ['x' => ['eee', 'ccc'], 'b' => ['zzz']];

$found = null;
$search = 'eee';

array_walk($a, function ($k, $v) use ($search, &$found) {
    if (in_array($search, $k)) {
        $found = $v;
    }
});

var_dump($found);

1

Versuche dies

<?php
 function recursive_array_search($needle,$haystack) {
    foreach($haystack as $key=>$value) {
        $current_key=$key;
        if($needle===$value OR (is_array($value) && 
            recursive_array_search($needle,$value) !== false)) {
             return $current_key;
        }
    }
    return false;
 }
 ?>

1

Einfach teilen, vielleicht kann das gefallen.

if( ! function_exists('arraySearchMulti')){
function arraySearchMulti($search,$key,$array,$returnKey=false)
{
    foreach ($array as $k => $val) {
        if (isset($val[$key])) {
            if ((string)$val[$key] == (string)$search) {
                return ($returnKey ? $k : $val);
            }
        }else{
            return (is_array($val) ? arraySearchMulti($search,$key,$val,$returnKey) : null);
        }
    }
    return null;
}}

0

Versuchen Sie dies auch

function search_in_array($srchvalue, $array)
{
    if (is_array($array) && count($array) > 0)
    {
        $foundkey = array_search($srchvalue, $array);
        if ($foundkey === FALSE)
        {
            foreach ($array as $key => $value)
            {
                if (is_array($value) && count($value) > 0)
                {
                    $foundkey = search_in_array($srchvalue, $value);
                    if ($foundkey != FALSE)
                        return $foundkey;
                }
            }
        }
        else
            return $foundkey;
    }
}

0
for( $i =0; $i < sizeof($allUsers); $i++)
    {   
    $NEEDLE1='firstname';
    $NEEDLE2='emailAddress';
    $sterm='Tofind';
     if(isset($allUsers[$i][$NEEDLE1]) && isset($allUsers[$i][$NEEDLE2])
        {
            $Fname= $allUsers[$i][$NEEDLE1];
            $Lname= $allUsers[$i][$NEEDLE2];

            $pos1 = stripos($Fname, $sterm);
            $pos2=stripos($Lname, $sterm);//not case sensitive 

            if($pos1 !== false ||$pos2 !== false)
            {$resultsMatched[] =$allUsers[$i];}
            else
            {   continue;}              
        }

}
Print_r($resultsMatched); //will give array for matched values even partially matched

Mit Hilfe des obigen Codes kann man alle (teilweise übereinstimmenden) Daten aus jeder Spalte im 2D-Array finden, so dass die Benutzer-ID nach Bedarf gefunden werden kann.


Bitte fügen Sie einen Satz hinzu, um zu erklären, warum dies die Frage beantwortet
Lorenz Meyer

Mit Hilfe des obigen Codes kann man alle (teilweise übereinstimmenden) Daten aus jeder Spalte im 2D-Array finden, so dass die Benutzer-ID wie in Frage angegeben gefunden werden kann
Sandeep Sharma

0

Wenn Sie die erstellte Funktion @mayhem erweitern, handelt es sich bei diesem Beispiel eher um eine "unscharfe" Suche, falls Sie nur einen Teil (die meisten ) einer Suchzeichenfolge abgleichen möchten :

 function searchArrayKeyVal($sKey, $id, $array) {
    foreach ($array as $key => $val) {
        if (strpos(strtolower($val[$sKey]), strtolower(trim($id))) !== false) {
            return $key;
        }
    }
         return false;
 }

Der Wert im Array lautet beispielsweise Willkommen in New York! und Sie wollten die erste Instanz von nur "New York!"


0
$search1 = 'demo';
$search2 = 'bob';
$arr = array('0' => 'hello','1' => 'test','2' => 'john','3' => array('0' => 'martin', '1' => 'bob'),'4' => 'demo');
foreach ($arr as $value) { 
    if (is_array($value)) { 
        if (in_array($search2, $value)) { 
            echo "successsfully";    
            //execute your code 
        }
    } else {  
        if ($value == $search1) { 
            echo "success";
        }
    }
 }

0

Wenn Frage dh

$a = [
     [
       "_id" => "5a96933414d48831a41901f2",
       "discount_amount" => 3.29,
       "discount_id" => "5a92656a14d488570c2c44a2",
     ],
     [
       "_id" => "5a9790fd14d48879cf16a9e8",
       "discount_amount" => 4.53,
       "discount_id" => "5a9265b914d488548513b122",
     ],
     [
       "_id" => "5a98083614d488191304b6c3",
       "discount_amount" => 15.24,
       "discount_id" => "5a92806a14d48858ff5c2ec3",
     ],
     [
       "_id" => "5a982a4914d48824721eafe3",
       "discount_amount" => 45.74,
       "discount_id" => "5a928ce414d488609e73b443",
     ],
    [
       "_id" => "5a982a4914d48824721eafe55",
       "discount_amount" => 10.26,
       "discount_id" => "5a928ce414d488609e73b443",
     ],
   ];

Ans:

function searchForId($id, $array) {
    $did=0;
    $dia=0;
   foreach ($array as $key => $val) {
       if ($val['discount_id'] === $id) {
           $dia +=$val['discount_amount'];
           $did++;
       }
   }
    if($dia != '') {
        echo $dia;
        var_dump($did);
    }
   return null;
};
print_r(searchForId('5a928ce414d488609e73b443',$a));

0

meine Lösung:

function searchArrayForField($array, $field, $value) {
    $i = 0;
    foreach ($array as &$row) {
        if ($row[$field] === $value) {
            return $i;
        }
        $i++
    }
    return '';
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.