I have a array list (for this example I'm using cell phones). I'm wanting to be able to search for multiple key/value pairs and return it's parent array index.
我有一个数组列表(对于这个例子,我使用的是手机)。我希望能够搜索多个键/值对并返回它的父数组索引。
For example, here is my array:
例如,这是我的数组:
// $list_of_phones (array)
Array
(
[0] => Array
(
[Manufacturer] => Apple
[Model] => iPhone 3G 8GB
[Carrier] => AT&T
)
[1] => Array
(
[Manufacturer] => Motorola
[Model] => Droid X2
[Carrier] => Verizon
)
)
I'm wanting to be able to do something like the following:
我想要能够做如下的事情:
// This is not a real function, just used for example purposes
$phone_id = multi_array_search( array('Manufacturer' => 'Motorola', 'Model' => 'Droid X2'), $list_of_phones );
// $phone_id should return '1', as this is the index of the result.
Any ideas or suggestions on how I can or should do this?
关于我如何能够或应该如何做的任何想法或建议?
6 个解决方案
#1
9
Perhaps this will be useful:
也许这会很有用:
/**
* Multi-array search
*
* @param array $array
* @param array $search
* @return array
*/
function multi_array_search($array, $search)
{
// Create the result array
$result = array();
// Iterate over each array element
foreach ($array as $key => $value)
{
// Iterate over each search condition
foreach ($search as $k => $v)
{
// If the array element does not meet the search condition then continue to the next element
if (!isset($value[$k]) || $value[$k] != $v)
{
continue 2;
}
}
// Add the array element's key to the result array
$result[] = $key;
}
// Return the result array
return $result;
}
// Output the result
print_r(multi_array_search($list_of_phones, array()));
// Array ( [0] => 0 [1] => 1 )
// Output the result
print_r(multi_array_search($list_of_phones, array('Manufacturer' => 'Apple')));
// Array ( [0] => 0 )
// Output the result
print_r(multi_array_search($list_of_phones, array('Manufacturer' => 'Apple', 'Model' => 'iPhone 6')));
// Array ( )
As the output shows, this function will return an array of all keys with elements which meet all the search criteria.
如输出所示,此函数将返回包含符合所有搜索条件的元素的所有键的数组。
#2
5
you may use array_intersect_key and array_intersect and array_search
您可以使用array_intersect_key和array_intersect以及array_search
check array_intersect_key php manual to get array of items with matching keys
检查array_intersect_key php手册以获取具有匹配键的项目数组
and array_intesect php manual to get array if items with matching values
和array_intesect php手册来获取具有匹配值的项目的数组
u can get value of key in array using $array[key]
你可以使用$ array [key]获取数组中键的值
and get key of value in array using array_search $key = array_search('green', $array);
使用array_search $ key = array_search('green',$ array)获取数组中的键值;
php.net/manual/en/function.array-search.php
php.net/manual/en/function.array-search.php
#3
3
I ended up doing the following. It's not pretty, but works very well. For anyone reading, feel free to update with a DRYer answer:
我最终做了以下事情。它不漂亮,但效果很好。对于阅读的任何人,请随时使用DRYer答案进行更新:
// Variables for this example
$carrier = 'Verizon';
$model = 'Droid X2';
$manufacturer = 'Motorola';
// The foreach loop goes through each key/value of $list_of_phones and checks
// if the given value is found in that particular array. If it is, it then checks
// a second parameter (model), and so on.
foreach ($list_of_phones as $key => $object)
{
if ( array_search($carrier, $object) )
{
if ( array_search($model, $object) )
{
if ( array_search($manufacturer, $object) )
{
// Return the phone from the $list_of_phones array
$phone = $list_of_phones[$key];
}
}
}
}
Works like a charm.
奇迹般有效。
#4
0
This way works for a multidimensinal array like yours:
这种方式适用于像你这样的多维数字阵列:
$test = array_intersect_key($list_of_phones, array(array("Manufacturer" => "Motorola", "Carrier" => "Verizon")));
#5
0
I expanded @MichaelRushton's code by adding support for different comparison operators:
我通过添加对不同比较运算符的支持来扩展@MichaelRushton的代码:
function multi_array_search ($array, $search) {
$result = [];
foreach ($array as $key => $value) { //iterate over each array element
foreach ($search as $k => $v) { //iterate over each search condition
$operator = $v[0];
$searchField = $v[1];
$searchVal = $v[2];
switch ($operator) {
case '=':
$cond = ($value[$searchField] != $searchVal);
break;
case '!=':
$cond = ($value[$searchField] == $searchVal);
break;
case '>':
$cond = ($value[$searchField] <= $searchVal);
break;
case '<':
$cond = ($value[$searchField] >= $searchVal);
break;
case '>=':
$cond = ($value[$searchField] < $searchVal);
break;
case '<=':
$cond = ($value[$searchField] > $searchVal);
break;
}
//if the array element does not meet the search condition then continue to the next element
if ((!isset($value[$searchField]) && $value[$searchField] !== null) || $cond) {
continue 2;
}
}
$result[] = $key; //add the array element's key to the result array
}
return $result;
}
//incoming data:
$phonesList = [
0 => [
'Manufacturer' => 'Apple',
'Model' => 'iPhone 3G 8GB',
'Carrier' => 'AT&T',
'Cost' => 100000
],
1 => [
'Manufacturer' => 'Motorola',
'Model' => 'Droid X2',
'Carrier' => 'Verizon',
'Cost' => 120000
],
2 => [
'Manufacturer' => 'Motorola',
'Model' => 'Droid X2',
'Carrier' => 'Verizon',
'Cost' => 150000
]
];
var_dump(multi_array_search($phonesList,
[ ['=', 'Manufacturer', 'Motorola'],
['>', 'Cost', '130000'] ]
));
//output:
array(1) { [0]=> int(2) }
#6
0
This is the same as @Boolean_Type but enhanced a bit to simplify things.
这与@Boolean_Type相同,但增强了一点以简化操作。
function multi_array_search($array, $search)
{
$result = array();
foreach ($array as $key => $val)
{
foreach ($search as $k => $v)
{
// We check if the $k has an operator.
$operator = '=';
if (preg_match('(<|<=|>|>=|!=|=)', $k, $m) === 1)
{
// We change the operator.
$operator = $m[0];
// We trim $k to remove white spaces before and after.
$k = trim(str_replace($m[0], '', $k));
}
switch ($operator)
{
case '=':
$cond = ($val[$k] != $v);
break;
case '!=':
$cond = ($val[$k] == $v);
break;
case '>':
$cond = ($val[$k] <= $v);
break;
case '<':
$cond = ($val[$k] >= $v);
break;
case '>=':
$cond = ($val[$k] < $sv);
break;
case '<=':
$cond = ($val[$k] > $sv);
break;
}
if (( ! isset($val[$k]) && $val[$k] !== null) OR $cond)
{
continue 2;
}
}
$result[] = $key;
}
return $result;
}
This way, you can simply search like this:
这样,您可以像这样搜索:
$keys = multi_array_search($phonesList, array(
'Manufacturer' => 'Motorola',
'Cost >' => '130000',
));
If found, you will have and array of indices like so: array(1, 25, 33)
(This is only an example).
如果找到,你将拥有像这样的索引数组:array(1,25,33)(这只是一个例子)。
#1
9
Perhaps this will be useful:
也许这会很有用:
/**
* Multi-array search
*
* @param array $array
* @param array $search
* @return array
*/
function multi_array_search($array, $search)
{
// Create the result array
$result = array();
// Iterate over each array element
foreach ($array as $key => $value)
{
// Iterate over each search condition
foreach ($search as $k => $v)
{
// If the array element does not meet the search condition then continue to the next element
if (!isset($value[$k]) || $value[$k] != $v)
{
continue 2;
}
}
// Add the array element's key to the result array
$result[] = $key;
}
// Return the result array
return $result;
}
// Output the result
print_r(multi_array_search($list_of_phones, array()));
// Array ( [0] => 0 [1] => 1 )
// Output the result
print_r(multi_array_search($list_of_phones, array('Manufacturer' => 'Apple')));
// Array ( [0] => 0 )
// Output the result
print_r(multi_array_search($list_of_phones, array('Manufacturer' => 'Apple', 'Model' => 'iPhone 6')));
// Array ( )
As the output shows, this function will return an array of all keys with elements which meet all the search criteria.
如输出所示,此函数将返回包含符合所有搜索条件的元素的所有键的数组。
#2
5
you may use array_intersect_key and array_intersect and array_search
您可以使用array_intersect_key和array_intersect以及array_search
check array_intersect_key php manual to get array of items with matching keys
检查array_intersect_key php手册以获取具有匹配键的项目数组
and array_intesect php manual to get array if items with matching values
和array_intesect php手册来获取具有匹配值的项目的数组
u can get value of key in array using $array[key]
你可以使用$ array [key]获取数组中键的值
and get key of value in array using array_search $key = array_search('green', $array);
使用array_search $ key = array_search('green',$ array)获取数组中的键值;
php.net/manual/en/function.array-search.php
php.net/manual/en/function.array-search.php
#3
3
I ended up doing the following. It's not pretty, but works very well. For anyone reading, feel free to update with a DRYer answer:
我最终做了以下事情。它不漂亮,但效果很好。对于阅读的任何人,请随时使用DRYer答案进行更新:
// Variables for this example
$carrier = 'Verizon';
$model = 'Droid X2';
$manufacturer = 'Motorola';
// The foreach loop goes through each key/value of $list_of_phones and checks
// if the given value is found in that particular array. If it is, it then checks
// a second parameter (model), and so on.
foreach ($list_of_phones as $key => $object)
{
if ( array_search($carrier, $object) )
{
if ( array_search($model, $object) )
{
if ( array_search($manufacturer, $object) )
{
// Return the phone from the $list_of_phones array
$phone = $list_of_phones[$key];
}
}
}
}
Works like a charm.
奇迹般有效。
#4
0
This way works for a multidimensinal array like yours:
这种方式适用于像你这样的多维数字阵列:
$test = array_intersect_key($list_of_phones, array(array("Manufacturer" => "Motorola", "Carrier" => "Verizon")));
#5
0
I expanded @MichaelRushton's code by adding support for different comparison operators:
我通过添加对不同比较运算符的支持来扩展@MichaelRushton的代码:
function multi_array_search ($array, $search) {
$result = [];
foreach ($array as $key => $value) { //iterate over each array element
foreach ($search as $k => $v) { //iterate over each search condition
$operator = $v[0];
$searchField = $v[1];
$searchVal = $v[2];
switch ($operator) {
case '=':
$cond = ($value[$searchField] != $searchVal);
break;
case '!=':
$cond = ($value[$searchField] == $searchVal);
break;
case '>':
$cond = ($value[$searchField] <= $searchVal);
break;
case '<':
$cond = ($value[$searchField] >= $searchVal);
break;
case '>=':
$cond = ($value[$searchField] < $searchVal);
break;
case '<=':
$cond = ($value[$searchField] > $searchVal);
break;
}
//if the array element does not meet the search condition then continue to the next element
if ((!isset($value[$searchField]) && $value[$searchField] !== null) || $cond) {
continue 2;
}
}
$result[] = $key; //add the array element's key to the result array
}
return $result;
}
//incoming data:
$phonesList = [
0 => [
'Manufacturer' => 'Apple',
'Model' => 'iPhone 3G 8GB',
'Carrier' => 'AT&T',
'Cost' => 100000
],
1 => [
'Manufacturer' => 'Motorola',
'Model' => 'Droid X2',
'Carrier' => 'Verizon',
'Cost' => 120000
],
2 => [
'Manufacturer' => 'Motorola',
'Model' => 'Droid X2',
'Carrier' => 'Verizon',
'Cost' => 150000
]
];
var_dump(multi_array_search($phonesList,
[ ['=', 'Manufacturer', 'Motorola'],
['>', 'Cost', '130000'] ]
));
//output:
array(1) { [0]=> int(2) }
#6
0
This is the same as @Boolean_Type but enhanced a bit to simplify things.
这与@Boolean_Type相同,但增强了一点以简化操作。
function multi_array_search($array, $search)
{
$result = array();
foreach ($array as $key => $val)
{
foreach ($search as $k => $v)
{
// We check if the $k has an operator.
$operator = '=';
if (preg_match('(<|<=|>|>=|!=|=)', $k, $m) === 1)
{
// We change the operator.
$operator = $m[0];
// We trim $k to remove white spaces before and after.
$k = trim(str_replace($m[0], '', $k));
}
switch ($operator)
{
case '=':
$cond = ($val[$k] != $v);
break;
case '!=':
$cond = ($val[$k] == $v);
break;
case '>':
$cond = ($val[$k] <= $v);
break;
case '<':
$cond = ($val[$k] >= $v);
break;
case '>=':
$cond = ($val[$k] < $sv);
break;
case '<=':
$cond = ($val[$k] > $sv);
break;
}
if (( ! isset($val[$k]) && $val[$k] !== null) OR $cond)
{
continue 2;
}
}
$result[] = $key;
}
return $result;
}
This way, you can simply search like this:
这样,您可以像这样搜索:
$keys = multi_array_search($phonesList, array(
'Manufacturer' => 'Motorola',
'Cost >' => '130000',
));
If found, you will have and array of indices like so: array(1, 25, 33)
(This is only an example).
如果找到,你将拥有像这样的索引数组:array(1,25,33)(这只是一个例子)。