in_array() 和多维数组
Posted
技术标签:
【中文标题】in_array() 和多维数组【英文标题】:in_array() and multidimensional array 【发布时间】:2011-05-06 21:54:15 【问题描述】:我使用in_array()
来检查一个值是否存在于如下数组中,
$a = array("Mac", "NT", "Irix", "Linux");
if (in_array("Irix", $a))
echo "Got Irix";
//print_r($a);
但是多维数组(如下)呢?如何检查该值是否存在于多维数组中?
$b = array(array("Mac", "NT"), array("Irix", "Linux"));
print_r($b);
或者当涉及到多维数组时我不应该使用in_array()
?
【问题讨论】:
接受的解决方案效果很好,但由于 php 的类型杂乱,在进行非严格比较时可能会导致意外结果。见:***.com/a/48890256/1579327 jwueller 的答案和我的答案都是您问题的正确答案。我提出了一个扩展 jwueller 函数的替代解决方案,以避免在进行非严格比较时由于 PHP 的类型杂乱而导致的常见错误。 一个班轮:var_dump(array_sum(array_map(function ($tmp) return in_array('NT',$tmp);, $multiarray)) > 0);
@AgniusVasiliauskas 聪明的解决方案,但如果第一级数组包含一个不是数组的项目,例如:$multiarray = array( "Hello", array("Mac", "NT"), array("Irix", "Linux"));
@Paolo 没有人会阻止您根据需要扩展匿名函数 - 在这种情况下,如果变量 $tmp
是具有 is_array()
函数的数组,则添加检查匿名函数。如果不是数组 - 继续不同的场景。
【参考方案1】:
我发现以下解决方案的代码不是很干净,但它可以工作。它用作递归函数。
function in_array_multi( $needle, $array, $strict = false )
foreach( $array as $value ) // Loop thorugh all values
// Check if value is aswell an array
if( is_array( $value ))
// Recursive use of this function
if(in_array_multi( $needle, $value ))
return true; // Break loop and return true
else
// Check if value is equal to needle
if( $strict === true )
if(strtolower($value) === strtolower($needle))
return true; // Break loop and return true
else
if(strtolower($value) == strtolower($needle))
return true; // Break loop and return true
return false; // Nothing found, false
【讨论】:
【参考方案2】:由于 PHP 5.6 有一个更好和更清洁原始答案的解决方案:
使用这样的多维数组:
$a = array(array("Mac", "NT"), array("Irix", "Linux"))
我们可以使用splat operator:
return in_array("Irix", array_merge(...$a), true)
如果你有这样的字符串键:
$a = array("a" => array("Mac", "NT"), "b" => array("Irix", "Linux"))
您必须使用array_values
以避免错误Cannot unpack array with string keys
:
return in_array("Irix", array_merge(...array_values($a)), true)
【讨论】:
【参考方案3】:我使用这种方法适用于任意数量的嵌套,不需要破解
<?php
$blogCategories = [
'programing' => [
'golang',
'php',
'ruby',
'functional' => [
'Erlang',
'Haskell'
]
],
'bd' => [
'mysql',
'sqlite'
]
];
$it = new RecursiveArrayIterator($blogCategories);
foreach (new RecursiveIteratorIterator($it) as $t)
$found = $t == 'Haskell';
if ($found)
break;
【讨论】:
【参考方案4】:我找到了非常小的简单解决方案:
如果你的数组是:
Array
(
[details] => Array
(
[name] => Dhruv
[salary] => 5000
)
[score] => Array
(
[ssc] => 70
[diploma] => 90
[degree] => 70
)
)
那么代码会是这样的:
if(in_array("5000",$array['details']))
echo "yes found.";
else
echo "no not found";
【讨论】:
【参考方案5】:对于多维儿童: in_array('needle', array_column($arr, 'key'))
对于一维儿童: in_array('needle', call_user_func_array('array_merge', $arr))
【讨论】:
整洁!谢谢@9ksoft 与array_column()
方法不同,call_user_func_array('array_merge')
方法也适用于基于索引的子数组,+1
太棒了!我投票支持这个解决方案。
很好,这行得通;并且为了减少开销(如果重要的话),将 array_column($arr, 'key') 隔离到一个命名的静态变量中,因为它基本上是一个名为 'key' 的数字索引数组;
【参考方案6】:
这也行。
function in_array_r($item , $array)
return preg_match('/"'.preg_quote($item, '/').'"/i' , json_encode($array));
用法:
if(in_array_r($item , $array))
// found!
【讨论】:
聪明,我喜欢这个。我想知道与foreach
循环相比性能如何。
工作就像一个魅力。
别误会,我喜欢这种方法。但是,当 json_encoding 具有与 $item
匹配的关联键的 $array
时,它将返回误报匹配。更不用说当字符串本身有双引号时可能无意中匹配字符串的一部分。我只会在像这个问题这样的小/简单情况下相信这个功能。
请注意,如果$item
包含破坏preg_match
的第一个参数(正则表达式)的字符,这将失败【参考方案7】:
jwueller
的accepted solution(在撰写本文时)function in_array_r($needle, $haystack, $strict = false)
foreach ($haystack as $item)
if (($strict ? $item === $needle : $item == $needle) || (is_array($item) && in_array_r($needle, $item, $strict)))
return true;
return false;
完全正确,但在进行弱比较时可能会出现意外行为(参数$strict = false
)。
由于 PHP 在比较不同类型的值时会出现类型混淆
"example" == 0
和
0 == "example"
评估true
,因为"example"
被转换为int
并转换为0
。
(见Why does PHP consider 0 to be equal to a string?)
如果这不是所需的行为,在进行非严格比较之前将数值转换为字符串会很方便:
function in_array_r($needle, $haystack, $strict = false)
foreach ($haystack as $item)
if( ! $strict && is_string( $needle ) && ( is_float( $item ) || is_int( $item ) ) )
$item = (string)$item;
if (($strict ? $item === $needle : $item == $needle) || (is_array($item) && in_array_r($needle, $item, $strict)))
return true;
return false;
【讨论】:
【参考方案8】:$userdb = Array
(
(0) => Array
(
('uid') => '100',
('name') => 'Sandra Shush',
('url') => 'urlof100'
),
(1) => Array
(
('uid') => '5465',
('name') => 'Stefanie Mcmohn',
('url') => 'urlof5465'
),
(2) => Array
(
('uid') => '40489',
('name') => 'Michael',
('url') => 'urlof40489'
)
);
$url_in_array = in_array('urlof5465', array_column($userdb, 'url'));
if($url_in_array)
echo 'value is in multidim array';
else
echo 'value is not in multidim array';
【讨论】:
虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高答案的长期价值。 6 年后,它给了我我需要的东西。array_column()
多维数组的完美答案【参考方案9】:
你可以这样使用
$result = array_intersect($array1, $array2);
print_r($result);
http://php.net/manual/tr/function.array-intersect.php
【讨论】:
【参考方案10】:我正在寻找一个函数,它可以让我在数组 (haystack) 中搜索字符串和数组(如针),所以我添加到 answer by @jwueller。
这是我的代码:
/**
* Recursive in_array function
* Searches recursively for needle in an array (haystack).
* Works with both strings and arrays as needle.
* Both needle's and haystack's keys are ignored, only values are compared.
* Note: if needle is an array, all values in needle have to be found for it to
* return true. If one value is not found, false is returned.
* @param mixed $needle The array or string to be found
* @param array $haystack The array to be searched in
* @param boolean $strict Use strict value & type validation (===) or just value
* @return boolean True if in array, false if not.
*/
function in_array_r($needle, $haystack, $strict = false)
// array wrapper
if (is_array($needle))
foreach ($needle as $value)
if (in_array_r($value, $haystack, $strict) == false)
// an array value was not found, stop search, return false
return false;
// if the code reaches this point, all values in array have been found
return true;
// string handling
foreach ($haystack as $item)
if (($strict ? $item === $needle : $item == $needle)
|| (is_array($item) && in_array_r($needle, $item, $strict)))
return true;
return false;
【讨论】:
【参考方案11】:我相信你现在可以使用array_key_exists:
<?php
$a=array("Mac"=>"NT","Irix"=>"Linux");
if (array_key_exists("Mac",$a))
echo "Key exists!";
else
echo "Key does not exist!";
?>
【讨论】:
【参考方案12】:这是我的提议基于 json_encode() 解决方案:
不区分大小写选项 返回计数而不是 true 数组中的任意位置(键和值)如果没有找到单词,它仍然返回 0 等于 false。
function in_array_count($needle, $haystack, $caseSensitive = true)
if(!$caseSensitive)
return substr_count(strtoupper(json_encode($haystack)), strtoupper($needle));
return substr_count(json_encode($haystack), $needle);
希望对你有帮助。
【讨论】:
请注意,此函数也匹配子字符串:例如00
到 10000
或 lo
到 Hello
。此外,如果针包含json_encode
转义的任何字符,例如双引号,则会失败。
当然这取决于你会做什么,但对我来说,这个解决方案执行速度很快,就足够了。【参考方案13】:
这样就可以了:
foreach($b as $value)
if(in_array("Irix", $value, true))
echo "Got Irix";
in_array
仅对一维数组进行操作,因此您需要遍历每个子数组并在每个子数组上运行 in_array
。
正如其他人所指出的,这仅适用于二维数组。如果您有更多嵌套数组,则递归版本会更好。有关示例,请参阅其他答案。
【讨论】:
但是,这只适用于一维。您必须创建一个递归函数才能检查每个深度。 我运行了代码,但它有一个错误 - Parse error: parse error in C:\wamp\www\000_TEST\php\php.in_array\index.php 在第 21 行 - 这是 if( in_array("Irix", $value) 谢谢。 @lauthiamkok:在上述行的末尾缺少一个)
。
谢谢,我修正了我的答案。当我输入太快并且不重新阅读我的代码时,就会发生这种情况。
您应该始终调用in_array()
,并将第三个参数设置为true
。在这里查看原因:***.com/questions/37080581/…【参考方案14】:
如果您知道要搜索哪一列,则可以使用 array_search() 和 array_column():
$userdb = Array
(
(0) => Array
(
('uid') => '100',
('name') => 'Sandra Shush',
('url') => 'urlof100'
),
(1) => Array
(
('uid') => '5465',
('name') => 'Stefanie Mcmohn',
('url') => 'urlof5465'
),
(2) => Array
(
('uid') => '40489',
('name') => 'Michael',
('url') => 'urlof40489'
)
);
if(array_search('urlof5465', array_column($userdb, 'url')) !== false)
echo 'value is in multidim array';
else
echo 'value is not in multidim array';
这个想法在 PHP 手册中 array_search() 的 cmets 部分;
【讨论】:
你也可以试试:in_array('value', array_column($arr, 'active'))array_column
需要 PHP 5.5+
本例中是否可以获取到匹配子数组的uid? @ethmz
这正是我想要的
找了好久这个解决方案终于完美了!【参考方案15】:
您总是可以序列化您的多维数组并执行strpos
:
$arr = array(array("Mac", "NT"), array("Irix", "Linux"));
$in_arr = (bool)strpos(serialize($arr),'s:4:"Irix";');
if($in_arr)
echo "Got Irix!";
我用过的各种文档:
strpos() serialize() Type Juggling or (bool)【讨论】:
错了。如果搜索字符串包含在某个数组值中(将在“mytoll Irixus”中找到“Irix”),您的函数也会返回 true。 我已经修正了我的答案。 @user3351722 这种方式可以在没有更多人(唯一的vale)时解决问题,并且它是动态的..就像这样 $in_arr = (bool)strpos(serialize($user_term_was_downloaded), 's: 3:"tid";s:2:"'.$value->tid.'";'); @I--我认为如果 Stack Overflow 上的任何人不想共享代码,他们不会发布代码。随意使用本网站上的任何代码做任何事情。我通常在代码 sn-p 上方添加一条注释,上面写着“感谢 Stack Overflow”,然后粘贴我从中找到代码的 URL。 有趣的答案,在某些情况下肯定有效,但不是全部。【参考方案16】:array_search 呢?根据https://gist.github.com/Ocramius/1290076 ..
似乎它比 foreach 快得多if( array_search("Irix", $a) === true)
echo "Got Irix";
【讨论】:
实际上 array_search 不是递归的,所以这不起作用。我希望它确实如此,因为它是如此干净和简单。 php.net/manual/en/function.array-search.php【参考方案17】:较短的版本,用于基于数据库结果集创建的多维数组。
function in_array_r($array, $field, $find)
foreach($array as $item)
if($item[$field] == $find) return true;
return false;
$is_found = in_array_r($os_list, 'os_version', 'XP');
如果 $os_list 数组在 os_version 字段中包含“XP”,将返回。
【讨论】:
【参考方案18】:它也可以首先从原始数组创建一个新的一维数组。
$arr = array("key1"=>"value1","key2"=>"value2","key3"=>"value3");
foreach ($arr as $row) $vector[] = $row['key1'];
in_array($needle,$vector);
【讨论】:
【参考方案19】:in_array()
不适用于多维数组。您可以编写一个递归函数来为您执行此操作:
function in_array_r($needle, $haystack, $strict = false)
foreach ($haystack as $item)
if (($strict ? $item === $needle : $item == $needle) || (is_array($item) && in_array_r($needle, $item, $strict)))
return true;
return false;
用法:
$b = array(array("Mac", "NT"), array("Irix", "Linux"));
echo in_array_r("Irix", $b) ? 'found' : 'not found';
【讨论】:
谢谢。功能优雅!爱它!谢谢。当我运行你的函数时,我怎么知道它返回 true 或 false,因为我的屏幕没有显示任何内容?谢谢。 我一直在寻找可以做到这一点的东西,你只是让我免于编写自己的东西 :) 效果很好。那么我们如何搜索和显示数组键呢?例如:$b = array(1 => array("Mac", "NT"), 3 => array("Irix", "Linux")); @D.Tate *** 上的代码在cc by-sa 3.0 下获得许可,需要注明出处(参见页脚)。您可以在此答案的永久链接中添加评论。 @blamb:这是故意的。这就是使函数递归的原因(例如,_r
,类似于print_r()
)。它下降到所有嵌套数组中以搜索该值,直到找不到更多数组为止。通过这种方式,您可以搜索任意复杂度的数组,而不仅仅是两层深度。【参考方案20】:
请尝试:
in_array("irix",array_keys($b))
in_array("Linux",array_keys($b["irix"])
我不确定是否需要,但这可能适合您的要求
【讨论】:
如何搜索数组键?$b
的数组键只是整数...在这些数组中没有指定的键...而array_keys($b["irix"])
只会抛出错误,因为$b["irix"]
不存在。【参考方案21】:
如果你的数组是这样的
$array = array(
array("name" => "Robert", "Age" => "22", "Place" => "TN"),
array("name" => "Henry", "Age" => "21", "Place" => "TVL")
);
使用这个
function in_multiarray($elem, $array,$field)
$top = sizeof($array) - 1;
$bottom = 0;
while($bottom <= $top)
if($array[$bottom][$field] == $elem)
return true;
else
if(is_array($array[$bottom][$field]))
if(in_multiarray($elem, ($array[$bottom][$field])))
return true;
$bottom++;
return false;
示例:echo in_multiarray("22", $array,"Age");
【讨论】:
【参考方案22】:很棒的功能,但在我将if($found) break;
添加到elseif
之前它对我不起作用
function in_array_r($needle, $haystack)
$found = false;
foreach ($haystack as $item)
if ($item === $needle)
$found = true;
break;
elseif (is_array($item))
$found = in_array_r($needle, $item);
if($found)
break;
return $found;
【讨论】:
【参考方案23】:这是我在php manual for in_array 中找到的第一个此类函数。评论部分的功能并不总是最好的,但如果它不能起到作用,你也可以在那里查看:)
<?php
function in_multiarray($elem, $array)
// if the $array is an array or is an object
if( is_array( $array ) || is_object( $array ) )
// if $elem is in $array object
if( is_object( $array ) )
$temp_array = get_object_vars( $array );
if( in_array( $elem, $temp_array ) )
return TRUE;
// if $elem is in $array return true
if( is_array( $array ) && in_array( $elem, $array ) )
return TRUE;
// if $elem isn't in $array, then check foreach element
foreach( $array as $array_element )
// if $array_element is an array or is an object call the in_multiarray function to this element
// if in_multiarray returns TRUE, than return is in array, else check next element
if( ( is_array( $array_element ) || is_object( $array_element ) ) && $this->in_multiarray( $elem, $array_element ) )
return TRUE;
exit;
// if isn't in array return FALSE
return FALSE;
?>
【讨论】:
elusive 的解决方案更好,因为它只适用于数组以上是关于in_array() 和多维数组的主要内容,如果未能解决你的问题,请参考以下文章