PHP中对包含多个数组的数组执行array_filter

3

我正在使用PHP中的array_filter来拆分包含多个数组的数组,当名为type的键的值与特定字符串匹配时。下面是示例代码:

示例数组

$arr[] = Array (
    [0] => Array ( [type] => Recurring ... )
    [1] => Array ( [type] => Single ... )
)

函数

function recurring($value)
{
    return ($value['type'] == 'Recurring');
}

function single($value)
{
    return ($value['type'] == 'Single');
}

分割数组

$recurring = array_filter($arr, 'recurring');
$single    = array_filter($arr, 'single');

这个方法可以运行,但我想知道是否有一种简化的方法,以便在未来创建其他过滤数组时不需要为每个数组创建一个新函数。
我已经开始使用闭包设置单个函数,但是我不确定如何做。有什么想法吗?
function key_type($value, $key, $string) {
    return $key == 'type' && $value == $string;
}

$recurring = array_filter($arr, 
key_type('Recurring'), ARRAY_FILTER_USE_BOTH);

$single = array_filter($pricing, 
key_type('Single'), ARRAY_FILTER_USE_BOTH);

使用闭包(匿名函数)有什么问题? - revo
array_filter($arr, key_type('Recurring'), ... - 这当然行不通,因为 key_type('Recurring') 是一个函数调用,而不仅仅是对函数的引用。在这种情况下,use 关键字非常有帮助,http://php.net/manual/en/functions.anonymous.php#example-165 - CBroe
@CBroe 如果该函数本身返回一个匿名函数,那么这个方法可能有效。然后你可以在返回的匿名函数上使用你提到的 use 关键字。我会发布一个答案。 - Cave Johnson
3个回答

2
一个方法可以按照以下方式进行,但说实话我不太喜欢这种方式。
$array = [['type' => 'Single'], ['type' => 'Recurring']];

function key_type($value) {
    global $string;
    return $value['type'] == $string;
}

($string = 'Recurring') && ($recurring = array_filter($array, 'key_type'));

($string = 'Single') && ($single = array_filter($array, 'key_type'));

另一种达到同样效果的方式是使用匿名函数(闭包)。不要过于考虑DRY,它看起来很好:

$array = [['type' => 'Single'], ['type' => 'Recurring']];

$recurring = array_filter($array, function($value) {
    return $value['type'] == 'Recurring';
});

$single = array_filter($array, function($value) {
    return $value['type'] == 'Single';
});

2
你可以实现你在问题中提出的想法。你只需要让key_type()函数返回一个可调用函数,这也是array_filter期望作为第二个参数的类型。你可以返回匿名函数,并使用use关键字将参数传递给匿名函数,就像CBroe在评论中提到的那样。

下面是一个例子:

function key_type($key) {
    return function($value) use ($key) {
        return $value['type'] == $key;
    };
}

$arr = array(
    array('type'=>'Recurring'),
    array('type'=>'Single')
);
print_r(array_filter($arr, key_type('Single'), ARRAY_FILTER_USE_BOTH));

以上代码将输出:
Array ( [1] => Array ( [type] => Single ) )

这种方法的优点在于,如果您需要更改逻辑以在所有需要使用您的过滤器的实例中使用它,您只需在key_type函数中更改一次即可。

0
这个任务可能更多地涉及分组而非过滤——从有限的示例数据中很难区分。
通常,我强烈建议不要在 PHP 代码中使用可变变量。出于可访问性的原因,最好将数据存储在数组中。
如果您的项目数据中仅包含两个提到的“type”值,则可以完全删除条件语句。
代码:(演示)
$array = [
    ['type' => 'Recurring', 'id' => 1],
    ['type' => 'Single',    'id' => 2],
    ['type' => 'Other',     'id' => 3],
    ['type' => 'Recurring', 'id' => 4],
    ['type' => 'Single',    'id' => 5],
];

$result = [];
foreach ($array as $row) {
    if (in_array($row['type'], ['Recurring', 'Single'])) {
        $result[strtolower($row['type'])][] = $row;
    }
}
var_export($result);

输出:

array (
  'recurring' => 
  array (
    0 => 
    array (
      'type' => 'Recurring',
      'id' => 1,
    ),
    1 => 
    array (
      'type' => 'Recurring',
      'id' => 4,
    ),
  ),
  'single' => 
  array (
    0 => 
    array (
      'type' => 'Single',
      'id' => 2,
    ),
    1 => 
    array (
      'type' => 'Single',
      'id' => 5,
    ),
  ),
)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接