可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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\' => \'\',
),
);
回答1:
Very simple:
function myfunction($products, $field, $value)
{
foreach($products as $key => $product)
{
if ( $product[$field] === $value )
return $key;
}
return false;
}
回答2:
Another poossible solution is based on the array_search()
function. You need to use PHP 5.5.0 or higher.
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\'
.
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.
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.
I created an array which contained 1000 arrays, the structure was like this (all data was randomized):
[
{
\"_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.
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.
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.
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.
Update III
Thanks to @mickmackusa for spotting several limitations on this method:
- This method will fail on associative keys.
- This method will only work on indexed subarrays (starting from 0 and have consecutively ascending keys).
回答3:
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:
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:
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:
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;
}
回答7:
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:
I would do like below, where $products
is the actual array given in the problem at the very beginning.
print_r(
array_search(\"breville-variable-temperature-kettle-BKE820XL\",
array_map(function($product){return $product[\"slug\"];},$products))
);