PHP多维数组搜索(按特定值查找键)

时间:2021-10-08 01:35:52

I have this multidimensional array. I need to search it and return only the key that matches the value of the "slug". I know there are other threads about searching multidimensional arrays, but I'm not really understanding enough to apply to my situation. Thanks very much for any help!

我有这个多维数组。我需要搜索它,只返回与“蛞蝓”值匹配的键。我知道搜索多维数组还有其他的线程,但是我还没有足够的理解来应用于我的情况。非常感谢您的帮助!

So I need a function like:

所以我需要一个函数:

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

Here's the 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'    => '',
        ),
);

8 个解决方案

#1


112  

Very simple:

非常简单:

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

#2


76  

Another poossible solution is based on the array_search() function. You need to use PHP 5.5.0 or higher.

另一个poossible解决方案基于array_search()函数。您需要使用PHP 5.5.0或更高版本。

Example

$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

Explanation

The function array_search() has two arguments. The first one is the value that you want to search. The second is where the function should search. The function array_column() gets the values of the elements which key is 'uid'.

函数array_search()有两个参数。第一个是你想要搜索的值。第二个是函数应该搜索的地方。函数array_column()获取元素的值,键为“uid”。

Summary

So you could use it as:

你可以把它当作:

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

or, if you prefer:

或者,如果你喜欢:

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

The original example(by xfoxawy) can be found on the DOCS.
The array_column() page.

原始示例(xfoxawy)可以在文档中找到。array_column()页。


Update

更新

Due to Vael comment I was curious, so I made a simple test to meassure the performance of the method that uses array_search and the method proposed on the accepted answer.

由于Vael的评论,我很好奇,所以我做了一个简单的测试来测量使用array_search的方法的性能,以及在已接受的答案上提出的方法。

I created an array which contained 1000 arrays, the structure was like this (all data was randomized):

我创建了一个包含1000个数组的数组,结构是这样的(所有数据都是随机的):

[
      {
            "_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"
      },...
]

I ran the search test 100 times searching for different values for the name field, and then I calculated the mean time in milliseconds. Here you can see an example.

我运行搜索测试100次,搜索name字段的不同值,然后计算平均时间(毫秒)。这里你可以看到一个例子。

Results were that the method proposed on this answer needed about 2E-7 to find the value, while the accepted answer method needed about 8E-7.

结果表明,在这个答案上提出的方法需要大约2E-7才能找到这个值,而被接受的答案则需要大约8E-7。

Like I said before both times are pretty aceptable for an application using an array with this size. If the size grows a lot, let's say 1M elements, then this little difference will be increased too.

就像我之前说过的,对于使用这个大小的数组的应用程序来说,这两个时间都是非常合适的。如果尺寸增加很多,假设是1M个元素,那么这个小的差异也会增加。

Update II

更新二世

I've added a test for the method based in array_walk_recursive which was mentionend on some of the answers here. The result got is the correct one. And if we focus on the performance, its a bit worse than the others examined on the test. In the test, you can see that is about 10 times slower than the method based on array_search. Again, this isn't a very relevant difference for the most of the applications.

我已经添加了一个基于array_walk_recursive的方法的测试,这个方法在这里的一些答案上是值得一提的。结果是正确的。如果我们把注意力集中在性能上,它会比其他在测试中测试的要差一些。在测试中,您可以看到这比基于array_search的方法慢了大约10倍。同样,对于大多数应用程序来说,这并不是非常相关的区别。

Update III

更新第三

Thanks to @mickmackusa for spotting several limitations on this method:

感谢@mickmackusa发现这种方法的一些限制:

  • This method will fail on associative keys.
  • 此方法将在关联键上失败。
  • This method will only work on indexed subarrays (starting from 0 and have consecutively ascending keys).
  • 这个方法只对索引子数组有效(从0开始并具有连续的升序键)。

#3


11  

This class method can search in array by multiple conditions:

这个类方法可以在数组中搜索多个条件:

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

Will produce:

会产生:

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

#4


2  

Use this function:

使用这个函数:

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;
}

}

}

and call function.

并调用函数。

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

#5


1  

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; 
} 

#6


1  

For the next visitor coming along: use the recursive array walk; it visits every "leaf" in the multidimensional array. Here's for inspiration:

接下来的访问者:使用递归数组walk;它访问多维数组中的每个“叶”。这是灵感:

function getMDArrayValueByKey($a, $k) {
    $r = [];
    array_walk_recursive ($a, 
                          function ($item, $key) use ($k, &$r) {if ($key == $k) $r[] = $item;}
                          );
    return $r;
}

#7


0  

Try this

试试这个

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;
    }

#8


0  

I would do like below, where $products is the actual array given in the problem at the very beginning.

我将如下所示,其中$products是问题一开始给出的实际数组。

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

print_r(函数(“breville-variable-temperature-kettle-BKE820XL”,到(功能(产品){返回$产品(“鼻涕虫”);},美元产品)));

#1


112  

Very simple:

非常简单:

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

#2


76  

Another poossible solution is based on the array_search() function. You need to use PHP 5.5.0 or higher.

另一个poossible解决方案基于array_search()函数。您需要使用PHP 5.5.0或更高版本。

Example

$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

Explanation

The function array_search() has two arguments. The first one is the value that you want to search. The second is where the function should search. The function array_column() gets the values of the elements which key is 'uid'.

函数array_search()有两个参数。第一个是你想要搜索的值。第二个是函数应该搜索的地方。函数array_column()获取元素的值,键为“uid”。

Summary

So you could use it as:

你可以把它当作:

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

or, if you prefer:

或者,如果你喜欢:

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

The original example(by xfoxawy) can be found on the DOCS.
The array_column() page.

原始示例(xfoxawy)可以在文档中找到。array_column()页。


Update

更新

Due to Vael comment I was curious, so I made a simple test to meassure the performance of the method that uses array_search and the method proposed on the accepted answer.

由于Vael的评论,我很好奇,所以我做了一个简单的测试来测量使用array_search的方法的性能,以及在已接受的答案上提出的方法。

I created an array which contained 1000 arrays, the structure was like this (all data was randomized):

我创建了一个包含1000个数组的数组,结构是这样的(所有数据都是随机的):

[
      {
            "_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"
      },...
]

I ran the search test 100 times searching for different values for the name field, and then I calculated the mean time in milliseconds. Here you can see an example.

我运行搜索测试100次,搜索name字段的不同值,然后计算平均时间(毫秒)。这里你可以看到一个例子。

Results were that the method proposed on this answer needed about 2E-7 to find the value, while the accepted answer method needed about 8E-7.

结果表明,在这个答案上提出的方法需要大约2E-7才能找到这个值,而被接受的答案则需要大约8E-7。

Like I said before both times are pretty aceptable for an application using an array with this size. If the size grows a lot, let's say 1M elements, then this little difference will be increased too.

就像我之前说过的,对于使用这个大小的数组的应用程序来说,这两个时间都是非常合适的。如果尺寸增加很多,假设是1M个元素,那么这个小的差异也会增加。

Update II

更新二世

I've added a test for the method based in array_walk_recursive which was mentionend on some of the answers here. The result got is the correct one. And if we focus on the performance, its a bit worse than the others examined on the test. In the test, you can see that is about 10 times slower than the method based on array_search. Again, this isn't a very relevant difference for the most of the applications.

我已经添加了一个基于array_walk_recursive的方法的测试,这个方法在这里的一些答案上是值得一提的。结果是正确的。如果我们把注意力集中在性能上,它会比其他在测试中测试的要差一些。在测试中,您可以看到这比基于array_search的方法慢了大约10倍。同样,对于大多数应用程序来说,这并不是非常相关的区别。

Update III

更新第三

Thanks to @mickmackusa for spotting several limitations on this method:

感谢@mickmackusa发现这种方法的一些限制:

  • This method will fail on associative keys.
  • 此方法将在关联键上失败。
  • This method will only work on indexed subarrays (starting from 0 and have consecutively ascending keys).
  • 这个方法只对索引子数组有效(从0开始并具有连续的升序键)。

#3


11  

This class method can search in array by multiple conditions:

这个类方法可以在数组中搜索多个条件:

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

Will produce:

会产生:

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

#4


2  

Use this function:

使用这个函数:

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;
}

}

}

and call function.

并调用函数。

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

#5


1  

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; 
} 

#6


1  

For the next visitor coming along: use the recursive array walk; it visits every "leaf" in the multidimensional array. Here's for inspiration:

接下来的访问者:使用递归数组walk;它访问多维数组中的每个“叶”。这是灵感:

function getMDArrayValueByKey($a, $k) {
    $r = [];
    array_walk_recursive ($a, 
                          function ($item, $key) use ($k, &$r) {if ($key == $k) $r[] = $item;}
                          );
    return $r;
}

#7


0  

Try this

试试这个

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;
    }

#8


0  

I would do like below, where $products is the actual array given in the problem at the very beginning.

我将如下所示,其中$products是问题一开始给出的实际数组。

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

print_r(函数(“breville-variable-temperature-kettle-BKE820XL”,到(功能(产品){返回$产品(“鼻涕虫”);},美元产品)));