根据列值过滤关联行,其中行位于 3d 数组的特定子数组中

问题描述 投票:0回答:4

我正在尝试 array_filter() 删除空白的嵌套数组,但我只取回所有嵌套数组。我知道我用错了,但看到了一个类似我正在尝试的案例。

这是数据:

[
    'ticket_number' => 'sdfsdfsdf 2',
    'strategy_id' => '5',
    'journal_entries_strategy_conditions' => [
        (int) 0 => [
            'strategies_condition_id' => ''
        ],
        (int) 1 => [
            'strategies_condition_id' => '1'
        ]
    ],
    'timeframe' => '',
]

我想删除

'strategies_condition_id' => ''
但我得到的只是

[
    (int) 0 => [
        'strategies_condition_id' => ''
    ],
    (int) 1 => [
        'strategies_condition_id' => '1'
    ]
]

我觉得我用对了:

debug(
  array_filter(
    $data['journal_entries_strategy_conditions'], 
    function($value) { return !is_null($value) && $value !== ''; }
  )
);
php arrays multidimensional-array filtering
4个回答
2
投票

传递给过滤函数的

$value
也是一个关联数组。

所以你必须检查“value of the value”,使用

current()
使过滤功能与键名无关,如果需要,可以使此代码可移植。我将函数参数命名为
$entry
以避免混淆:

$data= [
    'ticket_number' => 'sdfsdfsdf 2',
    'strategy_id' => '5',
    'journal_entries_strategy_conditions' => [
        (int) 0 => [
            'strategies_condition_id' => ''
        ],
        (int) 1 => [
            'strategies_condition_id' => '1'
        ]
    ],
    'timeframe' => '',
];


var_dump(
    array_filter(
        $data['journal_entries_strategy_conditions'],
        function($entry) {
            $value = current($entry);
            return !is_null($value) && $value !== '';
        }
    )
);

结果是:

array(1) {
  [1]=>
  array(1) {
    ["strategies_condition_id"]=>
    string(1) "1"
  }
}

1
投票

因为它是一个嵌套数组,所以您需要走更长的路并使用 array_column 然后用键的交集替换数组子数组。

$filtered = array_filter(array_column($arr['journal_entries_strategy_conditions'], 'strategies_condition_id'));

$arr['journal_entries_strategy_conditions'] = array_intersect_key($arr['journal_entries_strategy_conditions'], $filtered);

var_dump($arr);

https://3v4l.org/iC66a
通过将其设为单行,可以使它的可读性更差。

而且您不需要为此自定义功能。
Array_filter 默认删除 '' 和空值。


0
投票

由于您在过滤数组中有一个关联数组,从技术上讲它不是空的,这就是您的代码不起作用的原因。

如果你想要指定的键(假设键 does 存在)在过滤数组中不为空,只需传递该键值,如下所示:

$data = [
        (int) 0 => [
            'strategies_condition_id' => '',
            'test' => '',
            'asd' => 'asd'
        ],
        (int) 1 => [
            'strategies_condition_id' => '1'
        ]
    ];
$key = 'strategies_condition_id';
$result = array_filter($data, function($value) use ($key) {dump($value); return !is_null($value[$key]) && $value[$key] !== ''; });

输出:

array:1 [
  1 => array:1 [
    "strategies_condition_id" => "1"
  ]
]

Array

0
被跳过,因为它的
strategies_condition_id
键是空的。

还有另一种简单的方法来检查过滤数组中是否有任何空值:

$data = [
        (int) 0 => [
            'strategies_condition_id' => '',
            'test' => 'test'
        ],
        (int) 1 => [
            'strategies_condition_id' => '1'
        ],
        (int) 2 => [
            'strategies_condition_id' => '2',
            'test' => ''
        ]
    ];
array_filter($data, function($value) { return !in_array('',$value); });

输出:

array:1 [
  1 => array:1 [
    "strategies_condition_id" => "1"
  ]
]

0
投票

在特定的第一级元素上使用单个

array_filter()
即可完成工作。在函数的回调内部,不需要任何函数调用;只需访问目标关联子数组值并检查它是否为真。这和函数式风格编码一样简单。

代码:(演示

$array['journal_entries_strategy_conditions'] = array_filter(
    $array['journal_entries_strategy_conditions'],
    fn($row) => $row['strategies_condition_id']
);

经典循环的等价物可以有条件地使用

unset()
。 (演示

foreach ($array['journal_entries_strategy_conditions'] as $i => $row) {
    if (!$row['strategies_condition_id']) {
        unset($array['journal_entries_strategy_conditions'][$i]);
    }
}

或者如果你希望有一个重新索引的子数组,

array_splice()
是有帮助的。 (演示

foreach ($array['journal_entries_strategy_conditions'] as $i => $row) {
    if (!$row['strategies_condition_id']) {
        array_splice($array['journal_entries_strategy_conditions'], $i, 1);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.