PHP:如何使用 array_filter() 过滤数组键?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4260086/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 12:25:58  来源:igfitidea点击:

PHP: How to use array_filter() to filter array keys?

phparrayskey

提问by ma?ek

The callback function in array_filter()only passes in the array's values, not the keys.

回调函数 inarray_filter()只传递数组的值,而不是键。

If I have:

如果我有:

$my_array = array("foo" => 1, "hello" => "world");

$allowed = array("foo", "bar");

What's the best way to delete all keys in $my_arraythat are not in the $allowedarray?

删除$my_array不在$allowed数组中的所有键的最佳方法是什么?

Desired output:

期望的输出:

$my_array = array("foo" => 1);

采纳答案by Richard Turner

PHP 5.6 introduced a third parameter to array_filter(), flag, that you can set to ARRAY_FILTER_USE_KEYto filter by key instead of value:

PHP 5.6引入了第三个参数array_filter()flag,你可以设置为ARRAY_FILTER_USE_KEY通过键,而不是值进行筛选:

$my_array = ['foo' => 1, 'hello' => 'world'];
$allowed  = ['foo', 'bar'];
$filtered = array_filter(
    $my_array,
    function ($key) use ($allowed) {
        return in_array($key, $allowed);
    },
    ARRAY_FILTER_USE_KEY
);

Clearly this isn't as elegant as array_intersect_key($my_array, array_flip($allowed)), but it does offer the additional flexibility of performing an arbitrary test against the key, e.g. $allowedcould contain regex patterns instead of plain strings.

显然,这不如 优雅array_intersect_key($my_array, array_flip($allowed)),但它确实提供了对密钥执行任意测试的额外灵活性,例如$allowed可以包含正则表达式模式而不是纯字符串。

You can also use ARRAY_FILTER_USE_BOTHto have both the value and the key passed to your filter function. Here's a contrived example based upon the first, but note that I'd not recommend encoding filtering rules using $allowedthis way:

您还可以使用ARRAY_FILTER_USE_BOTH将值和键都传递给过滤器函数。这是一个基于第一个的人为示例,但请注意,我不建议使用$allowed这种方式对过滤规则进行编码:

$my_array = ['foo' => 1, 'bar' => 'baz', 'hello' => 'wld'];
$allowed  = ['foo' => true, 'bar' => true, 'hello' => 'world'];
$filtered = array_filter(
    $my_array,
    function ($val, $key) use ($allowed) { // N.b. $val, $key not $key, $val
        return isset($allowed[$key]) && (
            $allowed[$key] === true || $allowed[$key] === $val
        );
    },
    ARRAY_FILTER_USE_BOTH
); // ['foo' => 1, 'bar' => 'baz']

回答by Vincent Savard

With array_intersect_keyand array_flip:

随着array_intersect_keyarray_flip

var_dump(array_intersect_key($my_array, array_flip($allowed)));

array(1) {
  ["foo"]=>
  int(1)
}

回答by Christopher

I needed to do same, but with a more complex array_filteron the keys.

我需要做同样的事情,但array_filter按键更复杂。

Here's how I did it, using a similar method.

这是我如何做到的,使用类似的方法。

// Filter out array elements with keys shorter than 4 characters
$a = array(
  0      => "val 0", 
  "one"  => "val one", 
  "two"  => "val two", 
  "three"=> "val three", 
  "four" => "val four", 
  "five" => "val five", 
  "6"    => "val 6"
); 

$f = array_filter(array_keys($a), function ($k){ return strlen($k)>=4; }); 
$b = array_intersect_key($a, array_flip($f));
print_r($b);

This outputs the result:

这输出结果:

Array
(
    [three] => val three
    [four] => val four
    [five] => val five
)

回答by COil

Here is a more flexible solution using a closure:

这是使用闭包的更灵活的解决方案:

$my_array = array("foo" => 1, "hello" => "world");
$allowed = array("foo", "bar");
$result = array_flip(array_filter(array_flip($my_array), function ($key) use ($allowed)
{
    return in_array($key, $allowed);
}));
var_dump($result);

Outputs:

输出:

array(1) {
  'foo' =>
  int(1)
}

So in the function, you can do other specific tests.

所以在函数中,可以做其他具体的测试。

回答by Nicolas Zimmer

If you are looking for a method to filter an array by a string occurring in keys, you can use:

如果您正在寻找一种通过键中出现的字符串过滤数组的方法,您可以使用:

$mArray=array('foo'=>'bar','foo2'=>'bar2','fooToo'=>'bar3','baz'=>'nope');
$mSearch='foo';
$allowed=array_filter(
    array_keys($mArray),
    function($key) use ($mSearch){
        return stristr($key,$mSearch);
    });
$mResult=array_intersect_key($mArray,array_flip($allowed));

The result of print_r($mResult)is

结果print_r($mResult)

Array ( [foo] => bar [foo2] => bar2 [fooToo] => bar3 )


An adaption of this answer that supports regular expressions

此答案的改编版支持正则表达式

function array_preg_filter_keys($arr, $regexp) {
  $keys = array_keys($arr);
  $match = array_filter($keys, function($k) use($regexp) {
    return preg_match($regexp, $k) === 1;
  });
  return array_intersect_key($arr, array_flip($match));
}

$mArray = array('foo'=>'yes', 'foo2'=>'yes', 'FooToo'=>'yes', 'baz'=>'nope');

print_r(array_preg_filter_keys($mArray, "/^foo/i"));

Output

输出

Array
(
    [foo] => yes
    [foo2] => yes
    [FooToo] => yes
)

回答by flu

How to get the current key of an array when using array_filter

使用时如何获取数组的当前键 array_filter

Regardless of how I like Vincent's solution for Ma?ek's problem, it doesn't actually use array_filter. If you came here from a search engine you maybe where looking for something like this (PHP >= 5.3):

不管我如何喜欢 Vincent 对 Ma?ek 问题的解决方案,它实际上并没有使用array_filter. 如果您是从搜索引擎来到这里的,那么您可能正在寻找这样的东西(PHP >= 5.3):

$array = ['apple' => 'red', 'pear' => 'green'];
reset($array); // Unimportant here, but make sure your array is reset

$apples = array_filter($array, function($color) use ($&array) {
  $key = key($array);
  next($array); // advance array pointer

  return key($array) === 'apple';
}

It passes the array you're filtering as a reference to the callback. As array_filterdoesn't conventionally iterate over the array by increasing it's public internal pointer you have to advance it by yourself.

它传递您正在过滤的数组作为对回调的引用。由于array_filter通常不会通过增加它的公共内部指针来遍历数组,因此您必须自己推进它。

What's important here is that you need to make sure your array is reset, otherwise you might start right in the middle of it.

这里重要的是您需要确保您的阵列已重置,否则您可能会从中间开始。

In PHP >= 5.4you could make the callback even shorter:

PHP >= 5.4 中,您可以使回调更短:

$apples = array_filter($array, function($color) use ($&array) {
  return each($array)['key'] === 'apple';
}

回答by Gras Double

Starting from PHP 5.6, you can use the ARRAY_FILTER_USE_KEYflag in array_filter:

从 PHP 5.6 开始,您可以ARRAY_FILTER_USE_KEYarray_filter以下位置使用该标志:

$result = array_filter($my_array, function ($k) use ($allowed) {
    return in_array($k, $allowed);
}, ARRAY_FILTER_USE_KEY);


Otherwise, you can use this function (from TestDummy):


否则,您可以使用此函数(来自 TestDummy):

function filter_array_keys(array $array, $callback)
{
    $matchedKeys = array_filter(array_keys($array), $callback);

    return array_intersect_key($array, array_flip($matchedKeys));
}

$result = filter_array_keys($my_array, function ($k) use ($allowed) {
    return in_array($k, $allowed);
});


And here is an augmented version of mine, which accepts a callback or directly the keys:


这是我的一个增强版本,它接受回调或直接接受键:

function filter_array_keys(array $array, $keys)
{
    if (is_callable($keys)) {
        $keys = array_filter(array_keys($array), $keys);
    }

    return array_intersect_key($array, array_flip($keys));
}

// using a callback, like array_filter:
$result = filter_array_keys($my_array, function ($k) use ($allowed) {
    return in_array($k, $allowed);
});

// or, if you already have the keys:
$result = filter_array_keys($my_array, $allowed));


Last but not least, you may also use a simple foreach:


最后但并非最不重要的是,您还可以使用一个简单的foreach

$result = [];
foreach ($my_array as $key => $value) {
    if (in_array($key, $allowed)) {
        $result[$key] = $value;
    }
}

回答by Alastair

Here's a less flexible alternative using unset():

这是使用unset()的一个不太灵活的替代方案:

$array = array(
    1 => 'one',
    2 => 'two',
    3 => 'three'
);
$disallowed = array(1,3);
foreach($disallowed as $key){
    unset($array[$key]);
}

The result of print_r($array)being:

结果print_r($array)是:

Array
(
    [2] => two
)

This is not applicable if you want to keep the filteredvalues for later use but tidier, if you're certain that you don't.

如果您想保留过滤后的值以供以后使用但更整洁(如果您确定不这样做),则这不适用。

回答by Athari

Perhaps an overkill if you need it just once, but you can use YaLinqolibrary* to filter collections (and perform any other transformations). This library allows peforming SQL-like queries on objects with fluent syntax. Its wherefunction accepts a calback with two arguments: a value and a key. For example:

如果您只需要一次,可能有点矫枉过正,但您可以使用YaLinqo库* 来过滤集合(并执行任何其他转换)。该库允许使用流畅的语法对对象执行类似 SQL 的查询。它的where函数接受带有两个参数的回调:一个值和一个键。例如:

$filtered = from($array)
    ->where(function ($v, $k) use ($allowed) {
        return in_array($k, $allowed);
    })
    ->toArray();

(The wherefunction returns an iterator, so if you only need to iterate with foreachover the resulting sequence once, ->toArray()can be removed.)

(该where函数返回一个迭代器,因此如果您只需要对foreach结果序列迭代一次,则->toArray()可以将其删除。)

* developed by me

* 由我开发

回答by prince jose

array filter function from php:

来自 php 的数组过滤函数:

array_filter ( $array, $callback_function, $flag )

$array - It is the input array

$array - 这是输入数组

$callback_function - The callback function to use, If the callback function returns true, the current value from array is returned into the result array.

$callback_function - 要使用的回调函数,如果回调函数返回true,则将数组中的当前值返回到结果数组中。

$flag - It is optional parameter, it will determine what arguments are sent to callback function. If this parameter empty then callback function will take array values as argument. If you want to send array key as argument then use $flag as ARRAY_FILTER_USE_KEY. If you want to send both keys and values you should use $flag as ARRAY_FILTER_USE_BOTH.

$flag - 它是可选参数,它将确定发送给回调函数的参数。如果此参数为空,则回调函数将采用数组值作为参数。如果要将数组键作为参数发送,请使用 $flag 作为ARRAY_FILTER_USE_KEY。如果你想同时发送键和值,你应该使用 $flag 作为ARRAY_FILTER_USE_BOTH

For Example : Consider simple array

例如:考虑简单数组

$array = array("a"=>1, "b"=>2, "c"=>3, "d"=>4, "e"=>5);

If you want to filter array based on the array key, We need to use ARRAY_FILTER_USE_KEYas third parameterof array function array_filter.

如果要根据数组键过滤数组,我们需要使用ARRAY_FILTER_USE_KEY作为数组函数 array_filter 的第三个参数

$get_key_res = array_filter($array,"get_key",ARRAY_FILTER_USE_KEY );

If you want to filter array based on the array key and array value, We need to use ARRAY_FILTER_USE_BOTHas third parameter of array function array_filter.

如果要根据数组键和数组值过滤数组,我们需要使用ARRAY_FILTER_USE_BOTH作为数组函数 array_filter 的第三个参数。

$get_both = array_filter($array,"get_both",ARRAY_FILTER_USE_BOTH );

Sample Callback functions:

示例回调函数:

 function get_key($key)
 {
    if($key == 'a')
    {
        return true;
    } else {
        return false;
    }
}
function get_both($val,$key)
{
    if($key == 'a' && $val == 1)
    {
        return true;
    }   else {
        return false;
    }
}

It will output

它会输出

Output of $get_key is :Array ( [a] => 1 ) 
Output of $get_both is :Array ( [a] => 1 )