如何删除空的关联数组条目。

9

我有一个关联数组:$csv_arr

Array
(
    [0] => Array
        (
            [Enfalac] => alpha linolenic acid 300 mg
            [Enfapro] => alpha linolenic acid 200 mg
        )

    [1] => Array
        (
            [Enfalac] => arachidonic acid 170 mg
            [Enfapro] => 
        )

    [2] => Array
        (
            [Enfalac] => 
            [Enfapro] => 
        )

    [3] => Array
        (
            [Enfalac] => calcium 410 mg
            [Enfapro] => calcium 550 mg
        )
)

如何删除所有完全为空的条目,例如$csv_arr [2],但保留部分条目,例如$csv_arr [1]

我尝试了$csv_arr = array_filter(array_map('array_filter', $csv_arr));,但这会删除空元素:$csv_arr [1] ['Enfapro']

谢谢


1
你尝试过什么吗?比如循环或者使用array_filter函数? - John V.
1
如果可能的话,我更倾向于不使用循环,因为这是一个非常大的数组,所以最好使用内置函数。我知道如果不可能的话也可以理解,但我还是抱有希望。 - Andy Gee
1
循环遍历数组,然后再次循环遍历包含值的数组,并检查该值是否为空,然后取消设置它。 - Gacha
可能会有多达200个元素,但本质上它是一个可变数量的元素。如果有帮助的话,我事先会知道这些键的数量。 - Andy Gee
1
正如https://dev59.com/dmw15IYBdhLWcg3whMA1#6569117所述,PHP中没有惰性数组迭代。 - Gacha
显示剩余2条评论
6个回答

9
尝试一下这个,可能有点奇怪,但是:

array_filter($csv_arr, function($v){return array_filter($v) == array();});

这段代码完全没有经过测试,我也不记得这是否是闭包的正确语法,但它可能会起作用。

编辑(已经测试并且有效):

<?php
$csv_arr = array(
    0 => array(
            'Enfalac' => 'alpha linolenic acid 300 mg',
            'Enfapro' => 'alpha linolenic acid 200 mg'
        ),

    1 =>  array(
            'Enfalac' => 'arachidonic acid 170 mg',
            'Enfapro' => ''
        ),

    2 =>  array(
            'Enfalac' => '',
            'Enfapro' => ''
        ),

    3 =>  array(

            'Enfalac' => 'calcium 410 mg',
            'Enfapro' => 'calcium 550 mg'
        )
);
$c = function($v){
    return array_filter($v) != array();
};
var_dump(array_filter($csv_arr, $c));
?>

1
我喜欢这个想法,但我的PHP不支持,我也不确定如何修复它,所以我选择了一种implode变化。谢谢 - Andy Gee
@AndyGee 为了让我的示例更准确,我会以更友好的版本格式重新编写它。 - John V.
1
@AndyGee 你可以试试这个方法,可能比你的方法更快,我也不确定。 - John V.
有意思,我的基准测试说你的更快,也许是因为我只是用样本对其进行基准测试? - John V.

8
在你的情况下,这可能会更容易。我最近也遇到了同样的问题。只需使用
$csv_arr = array_filter($csv_arr, 'array_filter');

array_filter() 从数组中删除转换为 bool convert to false 的元素。这包括-例如-每个[]、null、''、0、false

它的作用

  1. 第一个 array_filter() 对每个子数组进行处理,并将其传递给第二个 array_filter()
  2. 第二个 array_filter() 删除每个 false 元素并返回其余部分。重要的是要注意,如果每个元素都转换为 false,则返回的数组将变为空数组。
  3. 第一个 array_filter() 采用来自第二个的结果并对其进行 false 检查。因此,如果返回了空数组,则会从数组中删除子数组。

为证明该案例,我使用了 John V. 的示例,并使用了单个 array_filter() 行:

<?php
$csv_arr = array(
    0 => array(
            'Enfalac' => 'alpha linolenic acid 300 mg',
            'Enfapro' => 'alpha linolenic acid 200 mg'
        ),

    1 =>  array(
            'Enfalac' => 'arachidonic acid 170 mg',
            'Enfapro' => ''
        ),

    2 =>  array(
            'Enfalac' => '',
            'Enfapro' => ''
        ),

    3 =>  array(

            'Enfalac' => 'calcium 410 mg',
            'Enfapro' => 'calcium 550 mg'
        )
);
print_r(array_filter($csv_arr, 'array_filter'));

3
如其他用户所述,你可以使用 array_filter() 方法来过滤数组的元素,它使用回调函数遍历数组中的每个值。其文档对其功能进行了很好的描述:

数组中的每个值应用回调函数进行过滤。如果回调函数返回true,则将当前值从数组返回到结果数组。

这意味着你可以传递回调函数,它可以是你自己的自定义函数或内置的 PHP 函数,但在这里,你只想删除空数组,那么你可以使用内置函数来传递给 array_filter 的回调函数。
我建议你使用 implode(string $separator, array $array) 函数,它使用分隔符将数组连接成字符串,如果没有指定分隔符,则使用空字符串连接。如果数组中所有的值都为 空、null 或 0,则它将返回 false,如果其中一个值有值,则返回 true,因此它将按照你的要求删除空关联数组。 我们将如下使用它:
$csv_arr = array_filter($csv_arr, 'implode');

它的作用是将每个元素传递给implode函数,并根据其返回值保留或从数组中删除元素,下面是完整示例:

完整示例:

<?php
$csv_arr = array
(
     array
        (
            'Enfalac' => 'alpha linolenic acid 300 mg',
            'Enfapro' => 'alpha linolenic acid 200 mg'
        ),

     array
        (
            'Enfalac' => 'arachidonic acid 170 mg',
            'Enfapro' => ''
        ),

     array
        (
            'Enfalac' => '',
            'Enfapro' => ''
        ),

     array
        (
            'Enfalac' => 'calcium 410 mg',
            'Enfapro' => 'calcium 550 mg'
        ),
);

$csv_arr = array_filter($csv_arr, 'implode');
print_r($csv_arr);

2
这个例子已经测试过并且可以正常运行:
   $csv_arr = [
           0 => [
               'Enfalac' => 'alpha linolenic acid 300 mg',
               'Enfapro' => 'alpha linolenic acid 200 mg',
           ],

           1 => [
               'Enfalac' => 'arachidonic acid 170 mg',
               'Enfapro' => '',
           ],

           2 => [
               'Enfalac' => '',
               'Enfapro' => '',
           ],

           3 => [

               'Enfalac' => 'calcium 410 mg',
               'Enfapro' => 'calcium 550 mg',
           ],
       ];

       var_dump(array_filter(array_map('array_filter', $csv_arr)));



0

好的,谢谢大家的帮助。我在循环中成功地完成了它。

if(implode('',$csv_arr[$i])==''){
    unset($csv_arr[$i]);
}

0

我认为这是更好和更合适的解决方案,

以下是代码:

$arr[0]['id'] = "id1";
$arr[0]['name'] = "testing";
$arr[1]['id'] = "id2";
$arr[1]['name'] = "another";
$arr[2]['id'] = "";
$arr[2]['name'] = "";
$d = array_keys($arr);
foreach($arr as $key=>$values){
    $a = array_keys($values);
    $n = count($a);
    for($i=0,$count=0;$i<$n;$i++){
        if($values[$a[$i]]==NULL){
            $count++;
        }
    }
    if($count==$n){

        unset($arr[$key]);
    }
}
echo "<pre>";
print_r($arr);

如果您希望这适用于更多嵌套的关联数组,您可以使用递归函数实现相同的功能。
谢谢, Nirav

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