如何按条件过滤数组

发布于 2024-08-06 12:45:59 字数 341 浏览 2 评论 0 原文

我有一个像这样的数组:

array("a" => 2, "b" => 4, "c" => 2, "d" => 5, "e" => 6, "f" => 2)

现在我想按某些条件过滤该数组,只保留值等于 2 的元素并删除值不为 2 的所有元素。

所以我的预期结果数组将是:

array("a" => 2, "c" => 2, "f" => 2)

注意:我想保留原始数组中的键。

如何使用 PHP 做到这一点?有什么内置功能吗?

I have an array like this:

array("a" => 2, "b" => 4, "c" => 2, "d" => 5, "e" => 6, "f" => 2)

Now I want to filter that array by some condition and only keep the elements where the value is equal to 2 and delete all elements where the value is NOT 2.

So my expected result array would be:

array("a" => 2, "c" => 2, "f" => 2)

Note: I want to keep the keys from the original array.

How can I do that with PHP? Any built-in functions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

热情消退 2024-08-13 12:45:59
$fullArray = array('a'=>2,'b'=>4,'c'=>2,'d'=>5,'e'=>6,'f'=>2);


function filterArray($value){
    return ($value == 2);
}

$filteredArray = array_filter($fullArray, 'filterArray');

foreach($filteredArray as $k => $v){
    echo "$k = $v";
}
$fullArray = array('a'=>2,'b'=>4,'c'=>2,'d'=>5,'e'=>6,'f'=>2);


function filterArray($value){
    return ($value == 2);
}

$filteredArray = array_filter($fullArray, 'filterArray');

foreach($filteredArray as $k => $v){
    echo "$k = $v";
}
无戏配角 2024-08-13 12:45:59

您必须以某种方式循环遍历数组并根据条件过滤每个元素。这可以通过多种方法来完成。

循环 while / for / foreach 方法

使用您想要的任何循环遍历数组,可能是 while forforeach。然后只需检查您的情况并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

You somehow have to loop through your array and filter each element by your condition. This can be done with various methods.

Loops while / for / foreach method

Loop through your array with any loop you want, may it be while, for or foreach. Then simply check for your condition and either unset() the elements if they don't meet your condition or write the elements, which meet the condition, into a new array.

Looping

//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

Just place your condition into the loop where the comment //condition is. The condition can just check for whatever you want and then you can either unset() the elements which don't meet your condition, and reindex the array with array_values() if you want, or write the elements in a new array which meet the condition.

//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() method

Another method is to use the array_filter() built-in function. It generally works pretty much the same as the method with a simple loop.

You just need to return TRUE if you want to keep the element in the array and FALSE if you want to drop the element out of the result array.

//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() method

preg_grep() is similar to array_filter() just that it only uses regular expression to filter the array. So you might not be able to do everything with it, since you can only use a regular expression as filter and you can only filter by values or with some more code by keys.

Also note that you can pass the flag PREG_GREP_INVERT as third parameter to invert the results.

//Filter by values
$newArray = preg_grep("/regex/", $array);

Common conditions

There are many common conditions used to filter an array of which all can be applied to the value and or key of the array. I will just list a few of them here:

//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
凯凯我们等你回来 2024-08-13 12:45:59

您可以迭代键的副本,以便能够在循环中使用 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;
    }
}

You can iterate on the copies of the keys to be able to use unset() in the loop:

foreach (array_keys($array) as $key) {
    if ($array[$key] != 2)  {
        unset($array[$key]);
    }
}

The advantage of this method is memory efficiency if your array contains big values - they are not duplicated.

EDIT I just noticed, that you actually only need the keys that have a value of 2 (you already know the value):

$keys = array();
foreach ($array as $key => $value) {
    if ($value == 2)  {
        $keys[] = $key;
    }
}
星星的轨迹 2024-08-13 12:45:59

我认为最快速、可读的内置函数是: array_intersect()

代码:(Demo)

$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
    )
);

I think the snappiest, readable built-in function is: array_intersect()

Code: (Demo)

$array = array("a" => 2, "b" => 4, "c" => 2, "d" => 5, "e" => 6, "f" => 2);
var_export(array_intersect($array, [2]));

Output:

array (
  'a' => 2,
  'c' => 2,
  'f' => 2,
)

Just make sure you declare the 2nd parameter as an array because that is the value type expected.

Now there is nothing wrong with writing out a foreach loop, or using array_filter(), they just have a more verbose syntax.

array_intersect() is also very easy to extend (include additional "qualifying" values) by adding more values to the 2nd parameter array.


From PHP7.4, arrow function syntax is available. This affords more concise code and the ability to access global variables without use.

Code: (Demo)

$haystack = [
    "a" => 2,
    "b" => 4,
    "c" => 2,
    "d" => 5,
    "e" => 6,
    "f" => 2
];
$needle = 2;

var_export(
    array_filter(
        $haystack,
        fn($v) => $v === $needle
    )
);
心舞飞扬 2024-08-13 12:45:59

这应该可行,但我不确定它的效率如何,因为您可能最终会复制大量数据。

$newArray = array_intersect_key(
                  $fullarray, 
                  array_flip(array_keys($fullarray, 2))
            );

This should work, but I'm not sure how efficient it is as you probably end up copying a lot of data.

$newArray = array_intersect_key(
                  $fullarray, 
                  array_flip(array_keys($fullarray, 2))
            );
破晓 2024-08-13 12:45:59

这可以使用闭包来处理。以下答案的灵感来自 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 ) 

This can be handled using a closure. The following answer is inspired by 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));

Contents of $filtered_array would now be

array ( ["a"] => 2 ["c"] => 2 ["f"] => 2 ) 
旧伤慢歌 2024-08-13 12:45:59

我可能会做这样的事情:

$newarray = array();
foreach ($jsonarray as $testelement){
    if ($testelement == 2){$newarray[]=$testelement}
}
$result = count($newarray);

I might do something like:

$newarray = array();
foreach ($jsonarray as $testelement){
    if ($testelement == 2){$newarray[]=$testelement}
}
$result = count($newarray);
手心的温暖 2024-08-13 12:45:59
  foreach ($aray as $key => $value) {
    if (2 != $value) {
      unset($array($key));
    }
  }

  echo 'Items in array:' . count($array);
  foreach ($aray as $key => $value) {
    if (2 != $value) {
      unset($array($key));
    }
  }

  echo 'Items in array:' . count($array);
一笑百媚生 2024-08-13 12:45:59

您可以执行以下操作:

$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);

You can do something like:

$array = array("a" => 2, "b" => 4, "c" => 2, "d" => 5, "e" => 6, "f" => 2);
$arrayFiltered = array_filter($array, function ($element) {
    return $element == 2;
});

or:

$arrayFiltered = array_filter($array, fn($element) => $element == 2);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文