PHP 多维数组搜索(按特定值查找键)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8102221/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PHP Multidimensional Array Searching (Find key by specific value)
提问by Ben Kouba
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!
我有这个多维数组。我需要搜索它并只返回与“slug”值匹配的键。我知道还有其他关于搜索多维数组的线程,但我对适用于我的情况的理解还不够。非常感谢您的帮助!
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' => '',
),
);
回答by Iván Rodríguez Torres
Another poossible solution is based on the array_search()
function. You need to use PHP 5.5.0or higher.
另一种可能的解决方案是基于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 提供)可以在DOCS上找到。
该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": ",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. Hereyou 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
这里的一些答案提到了该方法。得到的结果是正确的。如果我们专注于性能,它比测试中检查的其他人要差一些。在测试中,您可以看到这比基于 的方法慢了大约 10 倍array_search
。同样,对于大多数应用程序来说,这不是一个非常相关的差异。
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 开始并具有连续递增的键)。
回答by Aurelio De Rosa
Very simple:
很简单:
function myfunction($products, $field, $value)
{
foreach($products as $key => $product)
{
if ( $product[$field] === $value )
return $key;
}
return false;
}
回答by Fatalist
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"
}
}
回答by josef
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));
回答by Sam Kaz
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))
);
回答by Hans
For the next visitor coming along: use the recursive array walk; it visits every "leaf" in the multidimensional array. Here's for inspiration:
对于下一个访问者:使用递归数组遍历;它访问多维数组中的每个“叶子”。这是灵感:
function getMDArrayValueByKey($a, $k) {
$r = [];
array_walk_recursive ($a,
function ($item, $key) use ($k, &$r) {if ($key == $k) $r[] = $item;}
);
return $r;
}
回答by mikelee
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;
}
回答by pawan sen
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;
}