通过多个值过滤数组

时间:2019-03-23 13:22:00

标签: php multidimensional-array array-filter

我有一个多维数组,我想按许多值进行过滤。

$datas = [
    [
        'id' => 2135,
        'first_name' => 'John',
        'last_name' => 'Doe',
        'gender' => 'male'
    ],
    [
        'id' => 3245,
        'first_name' => 'Sally',
        'last_name' => 'Smith',
        'gender' => 'female'
    ],
    [
        'id' => 5342,
        'first_name' => 'Jane',
        'last_name' => 'Doe',
        'gender' => 'female'
    ],
    [
        'id' => 5623,
        'first_name' => 'Peter',
        'last_name' => 'Doe',
        'gender' => 'male'
    ],
    [
        'id' => 7216,
        'first_name' => 'Mike',
        'last_name' => 'Lill',
        'gender' => 'male'
    ]
];

我结合了array_filterarray_search的方法,并获得了不错的结果,但这仅过滤了一个值。我想要这样的东西...

array_filter(
    $datas,
    function ($key) {
        return array_search(['Doe', 'male'...], $key);
});

及其付出

array(
    array(
        'id' => 2135,
        'first_name' => 'John',
        'last_name' => 'Doe',
        'gender' => 'male'
    ),
    array(
        'id' => 5623,
        'first_name' => 'Peter',
        'last_name' => 'Doe',
        'gender' => 'male'
    )
)

2 个答案:

答案 0 :(得分:1)

当然,您可以简单地循环任何给定的输入,并检查给定的元素是否符合您实现的任何条件:

<?php
$input = [
    [
        'id' => 2135,
        'first_name' => 'John',
        'last_name' => 'Doe',
        'gender' => 'male'
    ],
    [
        'id' => 3245,
        'first_name' => 'Sally',
        'last_name' => 'Smith',
        'gender' => 'female'
    ],
    [
        'id' => 5342,
        'first_name' => 'Jane',
        'last_name' => 'Doe',
        'gender' => 'female'
    ],
    [
        'id' => 5623,
        'first_name' => 'Peter',
        'last_name' => 'Doe',
        'gender' => 'male'
    ],
    [
        'id' => 7216,
        'first_name' => 'Mike',
        'last_name' => 'Lill',
        'gender' => 'male'
    ]
];

$needles = ['Doe', 'male'];
$output = [];
array_walk($input, function($element) use ($needles, &$output) {
    $matches = true;
    foreach ($needles as $needle) {
        if (!in_array($needle, $element)) {
            $matches = false;
        }
    }
    if ($matches) {
        $output[] = $element;
    }
});

print_r($output);

显而易见的输出是:

Array
(
    [0] => Array
        (
            [id] => 2135
            [first_name] => John
            [last_name] => Doe
            [gender] => male
        )

    [1] => Array
        (
            [id] => 5623
            [first_name] => Peter
            [last_name] => Doe
            [gender] => male
        )

)

答案 1 :(得分:-2)

您希望根据多个限定值(无论其键如何)来过滤多维数组。

如果$datas来自数据库,则应该在sql中执行此过滤,以避免不必要地浪费资源。

如果您必须使用php进行过滤,那么array_filter()是一个直观且合乎逻辑的函数。

代码:(Demo

$needles = ['Doe', 'male'];

var_export(
    array_filter($datas, function($row) use ($needles) {
        return $needles == array_intersect($needles, $row);
    })
);

array_filter()在每个return中对布尔值进行迭代处理。 array_intersect($needles, $row)仅保留当前行中存在的$needles个元素。如果原始$needles包含与过滤后的$needles相同的数据,则返回true(保留行)。

从PHP7.4及更高版本开始,您可以使用箭头语法:

var_export(
    array_filter($datas, fn($row) => $needles == array_intersect($needles, $row))
);

输出:(来自任一片段)

array (
  0 => 
  array (
    'id' => 2135,
    'first_name' => 'John',
    'last_name' => 'Doe',
    'gender' => 'male',
  ),
  3 => 
  array (
    'id' => 5623,
    'first_name' => 'Peter',
    'last_name' => 'Doe',
    'gender' => 'male',
  ),
)

请注意,原始的第一级密钥已保留。如果您的项目要求多维数组重新索引,请在array_filter()内编写array_values()调用。


如果您想要一些其他技术来使用自己的数据运行自己的基准,这些语言构造也将提供过滤:(Demo

foreach ($datas as $row) {
    if ($needles == array_intersect($needles, $row)) {
        $result[] = $row;
    }
}
var_export($result);  // reindexed already

foreach ($datas as $index => $row) {
    if ($needles != array_intersect($needles, $row)) {
        unset($datas[$index]);
    }
}
var_export($datas);