php 如何按条件筛选数组

hpxqektj  于 2023-01-12  发布在  PHP
关注(0)|答案(9)|浏览(172)

我有一个这样的数组:

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

现在我想通过一些条件过滤数组,只保留值等于2的元素,删除值不等于2的所有元素。
因此,我的预期结果数组将是:

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

注意:我想保留原始数组中的键。
我怎么用PHP做到这一点?有内置函数吗?

ckx4rj1h

ckx4rj1h1#

$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";
}
baubqpgj

baubqpgj2#

你必须循环遍历数组,并根据条件过滤每个元素,这可以通过各种方法来实现。

循环while/for/foreach方法

用你想要的任何循环遍历你的数组,可以是whilefor或者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()内置函数,它的工作原理与简单循环的方法基本相同。
如果要将元素保留在数组中,只需返回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()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
yuvru6vn

yuvru6vn3#

你可以在键的副本上迭代,以便在循环中使用unset()

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

如果数组包含大值,此方法的优点是内存效率-它们不会重复。

EDIT我刚刚注意到,您实际上只需要值为2的键(您已经知道该值):

$keys = array();
foreach ($array as $key => $value) {
    if ($value == 2)  {
        $keys[] = $key;
    }
}
f8rj6qna

f8rj6qna4#

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

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

v8wbuo2f5#

这个问题可以通过闭包来解决。下面的答案是从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 )
x8diyxa7

x8diyxa76#

我认为最快、最可读的内置函数是: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
代码:(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
    )
);
i2byvkas

i2byvkas7#

我可能会这样做:

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

vddsk6oq8#

foreach ($aray as $key => $value) {
    if (2 != $value) {
      unset($array($key));
    }
  }

  echo 'Items in array:' . count($array);
yshpjwxd

yshpjwxd9#

您可以执行以下操作:

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

相关问题