简体   繁体   English

“简单”多级数组上的 PHP Array_filter

[英]PHP Array_filter on "simple" multi-level array

Can I and how can I use PHP's array_filter to filter the blank/nulls entries out of the following array structure?我可以以及如何使用 PHP 的array_filter从以下数组结构中过滤空白/空条目?

From: The array is from a PDO call using Fetch BOTH so the numeric and named values are always equal in this case. From:数组来自使用 Fetch BOTH 的 PDO 调用,因此在这种情况下,数值和命名值始终相等。

Array
(
    [2400] => Array
        (
            [0] => Array
                (
                    [value] => 7
                    [0] => 7
                )
            [1] => Array
                (
                    [value] => 61
                    [0] => 61
                )
            [2] => Array
                (
                    [value] => 42
                    [0] => 42
                )
            [3] => Array
                (
                    [value] => 
                    [0] => 
                )
        )
)

To:至:

Array
(
    [2400] => Array
        (
            [0] => Array
                (
                    [value] => 7
                    [0] => 7
                )
            [1] => Array
                (
                    [value] => 61
                    [0] => 61
                )
            [2] => Array
                (
                    [value] => 42
                    [0] => 42
                )
        )
)

I have tried我努力了

  • plain old array_filter普通的旧array_filter
  • array_filter(array, function($f){ ??? }) and not quite sure where to go from here... I was going to foreach the array to delve into it but how will that affect the entries through array_filter ? array_filter(array, function($f){ ??? })不太确定从这里去哪里...我打算对数组进行深入研究,但这将如何影响通过array_filter的条目? Won't a true/false return bring in the entire [2400] array portion?真/假返回不会带来整个 [2400] 数组部分吗? It just has me confused.它只是让我感到困惑。

Please suggest improvements to the question请对问题提出改进建议

Use array_filter and test the value element (or the 0 element, since they're equivalent).使用array_filter并测试value元素(或0元素,因为它们是等效的)。

$array[2400] = array_filter($array[2400], function($element) {
    return $element['value'];
});

To do it for all elements of the outer array, use a foreach loop.要对外部数组的所有元素执行此操作,请使用foreach循环。

foreach ($array as &$subarray) {
    $subarray = array_filter($subarray, function($element) {
        return $element['value'];
    });
}

or array_map :array_map

$array = array_map(function($subarray) {
    return array_filter($subarray, function($element) {
        return $element['value'];
    });
}, $array);

I think this can not be done using only array_filter function because sometimes you need to modify array elements but the array_filter function allows only to decide if the element should be excluded or not.我认为仅使用array_filter函数无法做到这一点,因为有时您需要修改数组元素,但array_filter函数仅允许决定是否应排除该元素。

For example in the main array element with index 2400 should be included in the result set but it's content should be modified.例如,索引为 2400 的主数组元素应包含在结果集中,但应修改其内容。

I wrote a simple function to do this, hope it might help.我写了一个简单的函数来做到这一点,希望它可能会有所帮助。 Well, you might use this for inspiration.好吧,你可能会用这个来获得灵感。 And it was interesting challenge for me as well.这对我来说也是一个有趣的挑战。

Below is my function with couple tests.下面是我的功能与几个测试。

<?php

function deepFilter(array $array)
{
    // Formally this is not need because if array is empty then $filteredArray will also be empty
    // but it simplifies the algorithm
    if (empty($array)) {
        return [];
    }

    $filteredArray = [];
    foreach ($array as $key => $value) {
        if (is_array($value) && !empty($value)) {
            $value = deepFilter($value);
        }
        if (!empty($value)) {
            $filteredArray[$key] = $value;
        }
    }

    return $filteredArray;
}

$testArray1 = [
    2400 => [
        0 => [
            'value' => 7,
            0 => 7,
        ],
        1 => [
            'value' => 61,
            0 => 61,
        ],
        2 => [
            'value' => 42,
            0 => 42,
        ],
        3 => [
            'value' => null,
            0 => null,
        ]
    ]
];

$testArray2 = [
    2400 => [
        0 => [
            'value' => 7,
            0 => 7,
        ],
        1 => [
            'value' => 61,
            0 => 61,
        ],
        2 => [
            'value' => 42,
            0 => 42,
        ],
        3 => null
    ],
    3243 => [
        0 => [
            'value' => 7,
            0 => null,
        ],
        1 => [
            'value' => null,
            0 => 61,
        ],
        2 => [
            'value' => 42,
            0 => 42,
        ],
        3 => null
    ]
];
var_export(deepFilter($testArray1));
var_export(deepFilter($testArray2));

The idea is very simple.这个想法很简单。

  1. Take an array and check elements one by one.取一个数组并逐个检查元素。
  2. If element is an array, apply the function for that element and check the result.如果 element 是一个数组,则对该元素应用函数并检查结果。 We can remove everything from child array and in this case we should not add it to results.我们可以从子数组中删除所有内容,在这种情况下,我们不应该将其添加到结果中。 Else if child has something remaining after cleanup include 'cleaned child' in our result set.否则,如果孩子在清理后还有剩余的东西,请在我们的结果集中包含“清理过的孩子”。
  3. If our element is not an array then include it only if it's not empty.如果我们的元素不是数组,则仅当它不为空时才包含它。

Please let me know if you find any mistakes or if it works for you or not.如果您发现任何错误或者它是否适合您,请告诉我。

If the array structure stays the same then this should work:如果数组结构保持不变,那么这应该有效:

foreach ($array as &$innerArray) {
    $innerArray = array_filter($innerArray, function($arr) { 
        return (!empty($arr[0]));
    });
}
unset($innerArray);

You can concisely filter the subset data by making iterated calls of array_filter() via array_map() .您可以通过array_map()array_filter()进行迭代调用,从而简洁地过滤子集数据。 You can avoid writing a custom function for array_filter() by calling the native function array_sum() (or array_product() ) -- this yields the correct truthy/falsey result because any data set with nulls will be calculated as 0 , and everything else with be non-zero ("truthy").您可以通过调用本机函数array_sum() (或array_product()来避免为array_filter()编写自定义函数——这会产生正确的真/假结果,因为任何具有空值的数据集都将被计算为0 ,以及其他所有内容非零(“真实”)。

Code: ( Demo )代码:(演示

var_export(
    array_map(fn($row) => array_filter($row, 'array_sum'), $array)
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM