it-swarm.com.de

PHP Mehrdimensionale Feldsuche (Schlüssel nach bestimmten Werten suchen)

Ich habe dieses mehrdimensionale Array. Ich muss es suchen und nur den Schlüssel zurückgeben, der dem Wert der "Slug" entspricht. Ich weiß, dass es andere Themen gibt, die sich mit der Suche nach mehrdimensionalen Arrays beschäftigen, aber ich verstehe nicht wirklich genug, um auf meine Situation zutreffen zu können. Vielen Dank für jede Hilfe!

Ich brauche also eine Funktion wie:

myfunction($products,'breville-one-touch-tea-maker-BTM800XL');
// returns 1

Hier ist das Array:

$products = array (
1  => array(
        'name'          => 'The Breville One-Touch Tea Maker',
        'slug'          => 'breville-one-touch-tea-maker-BTM800XL',
        'shortname'     => 'The One-Touch Tea Maker',
        'listprice'     => '299.99',
        'price'         => '249.99',
        'rating'        => '9.5',
        'reviews'       => '81',
        'buyurl'        => 'http://www.Amazon.com/The-Breville-One-Touch-Tea-Maker/dp/B003LNOPSG',
        'videoref1'     => 'xNb-FOTJY1c',
        'videoref2'     => 'WAyk-O2B6F8',
        'image'         => '812BpgHhjBML.jpg',
        'related1'      => '2',
        'related2'      => '3',
        'related3'      => '4',
        'bestbuy'       => '1',
        'quote'         => '',
        'quoteautor'    => 'K. Martino',
        ),

2  => array(
        'name'          => 'Breville Variable-Temperature Kettle BKE820XL',
        'slug'          => 'breville-variable-temperature-kettle-BKE820XL',
        'shortname'     => 'Variable Temperature Kettle',
        'listprice'     => '199.99',
        'price'         => '129.99',
        'rating'        => '9',
        'reviews'       => '78',
        'buyurl'        => 'http://www.Amazon.com/Breville-BKE820XL-Variable-Temperature-1-8-Liter-Kettle/dp/B001DYERBK',
        'videoref1'     => 'oyZWBD83xeE',
        'image'         => '41y2B8jSKmwL.jpg',
        'related1'      => '3',
        'related2'      => '4',
        'related3'      => '5',
        'bestbuy'       => '1',
        'quote'         => '',
        'quoteautor'    => '',
        ),
);
87
Ben Kouba

Sehr einfach:

function myfunction($products, $field, $value)
{
   foreach($products as $key => $product)
   {
      if ( $product[$field] === $value )
         return $key;
   }
   return false;
}
134
Aurelio De Rosa

Eine andere mögliche Lösung basiert auf der Funktion array_search(). Sie müssen PHP PHP 5.5.0 oder höher verwenden. 

Beispiel

$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'
    )
);

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

echo ("The key is: ".$key);
//This will output- The key is: 2

Erläuterung

Die Funktion array_search() hat zwei Argumente. Der erste ist der Wert, den Sie suchen möchten. Der zweite ist, wo die Funktion suchen soll. Die Funktion array_column() ruft die Werte der Elemente ab, deren Schlüssel 'uid' ist.

Zusammenfassung

Sie könnten es also verwenden als:

array_search('breville-one-touch-tea-maker-BTM800XL', array_column($products, 'slug'));

oder wenn Sie es bevorzugen:

// define function
function array_search_multidim($array, $column, $key){
    return (array_search($key, array_column($array, $column)););
}

// use it
array_search_multidim($products, 'slug', 'breville-one-touch-tea-maker-BTM800XL');

Das ursprüngliche Beispiel (von xfoxawy) ist auf DOCS zu finden.
Die array_column()Seite .


Update

Aufgrund des Kommentars von Vael war ich neugierig und habe daher einen einfachen Test durchgeführt, um die Leistung der Methode, die array_search verwendet, und der vorgeschlagenen Methode für die akzeptierte Antwort zu messen. 

Ich habe ein Array erstellt, das 1000 Arrays enthielt. Die Struktur war wie folgt (alle Daten wurden randomisiert):

[
      {
            "_id": "57fe684fb22a07039b3f196c",
            "index": 0,
            "guid": "98dd3515-3f1e-4b89-8bb9-103b0d67e613",
            "isActive": true,
            "balance": "$2,372.04",
            "picture": "http://placehold.it/32x32",
            "age": 21,
            "eyeColor": "blue",
            "name": "Green",
            "company": "MIXERS"
      },...
]

Ich habe den Suchtest 100 Mal nach verschiedenen Werten für das Namensfeld gesucht und dann die mittlere Zeit in Millisekunden berechnet. Hier Sie können ein Beispiel sehen.

Das Ergebnis war, dass die in dieser Antwort vorgeschlagene Methode ungefähr 2E-7 benötigte, um den Wert zu ermitteln, während die akzeptierte Antwortmethode ungefähr 8E-7 benötigte.

Wie ich schon sagte, sind beide Zeiten für eine Anwendung mit einem Array dieser Größe ziemlich akzeptabel. Wenn die Größe stark zunimmt, sagen wir 1M-Elemente, wird auch dieser kleine Unterschied größer. 

Update II

Ich habe einen Test für die Methode hinzugefügt, die in array_walk_recursive basiert und in einigen Antworten erwähnt wurde. Das Ergebnis ist das richtige. Und wenn wir uns auf die Leistung konzentrieren, ist es etwas schlechter als die anderen, die beim test untersucht wurden. Im Test können Sie sehen, dass dies etwa zehnmal langsamer ist als die auf array_search basierende Methode. Dies ist wiederum kein sehr relevanter Unterschied für die meisten Anwendungen. 

Update III

Vielen Dank an @mickmackusa für die Feststellung einiger Einschränkungen dieser Methode:

  • Diese Methode schlägt bei assoziativen Schlüsseln fehl. 
  • Diese Methode funktioniert nur bei indizierten Subarrays (beginnend mit 0 und aufsteigend nacheinander).

Diese Klassenmethode kann im Array unter mehreren Bedingungen suchen:

class Stdlib_Array
{
    public static function multiSearch(array $array, array $pairs)
    {
        $found = array();
        foreach ($array as $aKey => $aVal) {
            $coincidences = 0;
            foreach ($pairs as $pKey => $pVal) {
                if (array_key_exists($pKey, $aVal) && $aVal[$pKey] == $pVal) {
                    $coincidences++;
                }
            }
            if ($coincidences == count($pairs)) {
                $found[$aKey] = $aVal;
            }
        }

        return $found;
    }    
}

// Example:

$data = array(
    array('foo' => 'test4', 'bar' => 'baz'),
    array('foo' => 'test',  'bar' => 'baz'),
    array('foo' => 'test1', 'bar' => 'baz3'),
    array('foo' => 'test',  'bar' => 'baz'),
    array('foo' => 'test',  'bar' => 'baz4'),
    array('foo' => 'test4', 'bar' => 'baz1'),
    array('foo' => 'test',  'bar' => 'baz1'),
    array('foo' => 'test3', 'bar' => 'baz2'),
    array('foo' => 'test',  'bar' => 'baz'),
    array('foo' => 'test',  'bar' => 'baz'),
    array('foo' => 'test4', 'bar' => 'baz1')
);

$result = Stdlib_Array::multiSearch($data, array('foo' => 'test4', 'bar' => 'baz1'));

var_dump($result);

Wird herstellen:

array(2) {
  [5]=>
  array(2) {
    ["foo"]=>
    string(5) "test4"
    ["bar"]=>
    string(4) "baz1"
  }
  [10]=>
  array(2) {
    ["foo"]=>
    string(5) "test4"
    ["bar"]=>
    string(4) "baz1"
  }
}
12
Fatalist

Verwenden Sie diese Funktion:

function searchThroughArray($search,array $lists){
try{
    foreach ($lists as $key => $value) {
        if(is_array($value)){
            array_walk_recursive($value, function($v, $k) use($search ,$key,$value,&$val){
                if(strpos($v, $search) !== false )  $val[$key]=$value;
            });
    }else{
            if(strpos($value, $search) !== false )  $val[$key]=$value;
        }

    }
    return $val;

}catch (Exception $e) {
    return false;
}

}

und Funktion aufrufen.

print_r(searchThroughArray('breville-one-touch-tea-maker-BTM800XL',$products));
4
josef

Für den nächsten kommenden Besucher: Verwenden Sie den rekursiven Array-Spaziergang. Es besucht jedes "Blatt" im mehrdimensionalen Array. Hier ist zur Inspiration:

function getMDArrayValueByKey($a, $k) {
    $r = [];
    array_walk_recursive ($a, 
                          function ($item, $key) use ($k, &$r) {if ($key == $k) $r[] = $item;}
                          );
    return $r;
}
1
Hans
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; 
} 
1
mikelee

Versuche dies

function recursive_array_search($needle,$haystack) {
        foreach($haystack as $key=>$value) {
            $current_key=$key;
            if($needle==$value['uid'] OR (is_array($value) && recursive_array_search($needle,$value) !== false)) {
                return $current_key;
            }
        }
        return false;
    }
0
pawan sen

Ich möchte das unten machen, wobei $products das eigentliche Array ist, das zu Beginn des Problems angegeben wurde.

print_r(
  array_search("breville-variable-temperature-kettle-BKE820XL", 
  array_map(function($product){return $product["slug"];},$products))
);
0
Sam Kaz