我有一个像这样的数组:
array("a" => 2, "b" => 4, "c" => 2, "d" => 5, "e" => 6, "f" => 2)
现在我想通过某种条件过滤该数组,只保留值等于 2 的元素并删除值不为 2 的所有元素。
所以我的预期结果数组是:
array("a" => 2, "c" => 2, "f" => 2)
注意:我想保留原始数组中的键。
如何使用 PHP 做到这一点?有内置功能吗?
$fullArray = array('a'=>2,'b'=>4,'c'=>2,'d'=>5,'e'=>6,'f'=>2);
$filteredArray = array_filter($fullArray, fn ($value) => $value === 2);
foreach($filteredArray as $k => $v){
echo "$k = $v";
}
您必须以某种方式循环遍历数组并根据条件过滤每个元素。这可以通过多种方法来完成。
while
/ for
/ foreach
方法使用您想要的任何循环遍历数组,可以是
while
、for
或 foreach
。然后只需检查您的条件,如果不满足您的条件,则 unset()
元素,或者将满足条件的元素写入新数组。
//while loop
while(list($key, $value) = each($array)){
//condition
}
//for loop
$keys = array_keys($array);
for($counter = 0, $length = count($array); $counter < $length; $counter++){
$key = $keys[$counter];
$value = $array[$key];
//condition
}
//foreach loop
foreach($array as $key => $value){
//condition
}
只需将您的条件放入注释
//condition
所在的循环中即可。条件可以只检查您想要的任何内容,然后您可以 unset()
不满足您的条件的元素,并使用 array_values()
重新索引数组(如果需要),或者将元素写入新数组中满足条件。
//Pseudo code
//Use one of the two ways
if(condition){ //1. Condition fulfilled
$newArray[ ] = $value;
//↑ Put '$key' there, if you want to keep the original keys
//Result array is: $newArray
} else { //2. Condition NOT fulfilled
unset($array[$key]);
//Use array_values() after the loop if you want to reindex the array
//Result array is: $array
}
array_filter()
方法另一种方法是使用
array_filter()
内置函数。它的工作原理通常与简单循环的方法几乎相同。
如果您想将元素保留在数组中,则只需返回
TRUE
;如果您想将元素从结果数组中删除,则只需返回 FALSE
。
//Anonymous function
$newArray = array_filter($array, function($value, $key){
//condition
}, ARRAY_FILTER_USE_BOTH);
//Function name passed as string
function filter($value, $key){
//condition
}
$newArray = array_filter($array, "filter", ARRAY_FILTER_USE_BOTH);
//'create_function()', NOT recommended
$newArray = array_filter($array, create_function('$value, $key', '/* condition */'), ARRAY_FILTER_USE_BOTH);
preg_grep()
方法preg_grep()
与array_filter()
类似,只是它只使用正则表达式来过滤数组。因此,您可能无法用它做所有事情,因为您只能使用正则表达式作为过滤器,并且只能按值或按键使用更多代码进行过滤。
另请注意,您可以传递标志
PREG_GREP_INVERT
作为第三个参数来反转结果。
//Filter by values
$newArray = preg_grep("/regex/", $array);
用于过滤数组的常见条件有很多,其中所有条件都可以应用于数组的值和/或键。我在这里只列出其中一些:
//Odd values
return $value & 1;
//Even values
return !($value & 1);
//NOT null values
return !is_null($value);
//NOT 0 values
return $value !== 0;
//Contain certain value values
return strpos($value, $needle) !== FALSE; //Use 'use($needle)' to get the var into scope
//Contain certain substring at position values
return substr($value, $position, $length) === $subString;
//NOT 'empty'(link) values
array_filter($array); //Leave out the callback parameter
您可以迭代键的副本,以便能够在循环中使用
unset()
:
foreach (array_keys($array) as $key) {
if ($array[$key] != 2) {
unset($array[$key]);
}
}
如果您的数组包含大值,此方法的优点是内存效率 - 它们不会重复。
编辑我刚刚注意到,你实际上只需要值为2的键(你已经知道这个值):
$keys = array();
foreach ($array as $key => $value) {
if ($value == 2) {
$keys[] = $key;
}
}
我认为最快速、可读的内置函数是:array_intersect()
代码:(演示)
$array = array("a" => 2, "b" => 4, "c" => 2, "d" => 5, "e" => 6, "f" => 2);
var_export(array_intersect($array, [2]));
输出:
array (
'a' => 2,
'c' => 2,
'f' => 2,
)
只需确保将第二个参数声明为数组,因为这是预期的值类型。
现在编写 foreach 循环或使用
array_filter()
没有任何问题,它们只是有更详细的语法。
通过向第二个参数数组添加更多值,array_intersect()
也很容易扩展(包括额外的“限定”值)。
从 PHP7.4 开始,可以使用箭头函数语法。这提供了更简洁的代码,并且能够访问全局变量,而无需
use
。
代码:(演示)
$haystack = [
"a" => 2,
"b" => 4,
"c" => 2,
"d" => 5,
"e" => 6,
"f" => 2
];
$needle = 2;
var_export(
array_filter(
$haystack,
fn($v) => $v === $needle
)
);
这应该可行,但我不确定它的效率如何,因为您可能最终会复制大量数据。
$newArray = array_intersect_key(
$fullarray,
array_flip(array_keys($fullarray, 2))
);
这可以使用闭包来处理。以下答案的灵感来自于 PHP The Right Way:
//This will create an anonymous function that will filter the items in the array by the value supplied
function cb_equal_to($val)
{
return function($item) use ($val) {
return $item == $val;
};
}
$input = array("a" => 2, "b" => 4, "c" => 2, "d" => 5, "e" => 6, "f" => 2);
// Use array_filter on a input with a selected filter function
$filtered_array = array_filter($input, cb_equal_to(2));
$filtered_array 的内容现在是
array ( ["a"] => 2 ["c"] => 2 ["f"] => 2 )
我可能会做这样的事情:
$newarray = array();
foreach ($jsonarray as $testelement){
if ($testelement == 2){$newarray[]=$testelement}
}
$result = count($newarray);
foreach ($aray as $key => $value) {
if (2 != $value) {
unset($array($key));
}
}
echo 'Items in array:' . count($array);
你可以这样做:
$array = array("a" => 2, "b" => 4, "c" => 2, "d" => 5, "e" => 6, "f" => 2);
$arrayFiltered = array_filter($array, function ($element) {
return $element == 2;
});
或:
$arrayFiltered = array_filter($array, fn($element) => $element == 2);