从二维数组中删除行,其中在平面黑名单数组中找到特定列值[重复]

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

需要从数组 A 中消除数组 B 上不存在的键“service_code”值。在示例中,数组 B 上仅存在“SAF”。尝试了各种 array_intersect 函数,但没有成功。我相信一定有一种我不知道的方法来完成这个任务,而不是做一个循环。如有必要,我还可以通过删除 array_keys 来反转数组 B。

数组A

Array
(
    [1] => Array
        (
            [id] => 2
            [service_name] => Carpet Cleaning
            [type] => 
            [category_name] => Household
            [service_code] => SAF
            [category_code] => AA
        )

    [2] => Array
        (
            [id] => 3
            [service_name] => Floor Cleaning
            [type] => 
            [category_name] => Household
            [service_code] => MHSAF
            [category_code] => AA
        )

    [3] => Array
        (
            [id] => 4
            [service_name] => Lawn Service
            [type] => 
            [category_name] => Landscape
            [service_code] => GHF
            [category_code] => AA
        )
)

数组B

Array
(
    [0] => SAF
    [1] => SA
    [2] => MM
    [3] => METH
    [4] => OTPA
    [5] => OTP
    [6] => CBT
    [7] => SACA
    [8] => TRC
    [9] => REBT
)

预期结果

Array
(
    [1] => Array
        (
            [id] => 2
            [service_name] => Carpet Cleaning
            [type] => 
            [category_name] => Household
            [service_code] => SAF
            [category_code] => AA
        )
)
php arrays multidimensional-array filtering array-difference
3个回答
2
投票

最终,无论这些数据结构如何,您都会执行循环,即使“循环”隐藏在像

array_filter()
这样的函数调用中。

我的第一个建议是如果可能的话更改数组 B,这样您就不需要迭代它来查看数组中是否存在值。 数据结构如下:

[
  'SAF' => 1,
  'SA' => 1,
   ...
]

您可以轻松地在数组上执行

array_flip()
来实现这样的数据结构。

键包含您要查找的值的结构将允许您执行 O(1) 查找(而不是 O(n))来检查数组 A 中的服务代码。

您的代码可能如下所示:

$result = array_filter($array_a, function($item, $k) use ($array_b) {
    return array_key_exists($item['service_code'], $array_b);   
});

如果您无法按照描述更改数组 b,则需要在

in_array()
操作中迭代数组 B(这就是调用
array_filter
函数时发生的情况):

$result = array_filter($array_a, function($item, $k) use ($array_b) {
    return in_array($item['service_code'], $array_b);  
});

第一个解决方案的运行时间复杂度为 O(n),其中 n 是数组 A 中的元素数量。

第二个解决方案的运行时间复杂度为 O(n*m),其中 m 是数组 B 的元素数量(n 仍然是数组 A 中的元素数量)。

由于第二种解决方案表现不佳,您可以使用

array_flip()

进行优化
$service_code_keys = array_flip($array_b);
$result = array_filter(
    $array_a,
    function($item, $k) use ($service_code_keys) {
        return array_key_exists($item['service_code'], $service_code_keys); 
    }  
);

当您进行一次 O(m) 命中来迭代和翻转数组 B 时,这会将操作复杂性提高到 O(m + n)。尽管如此,这比

in_array()
解决方案有了很大的改进。


2
投票

您的解决方案是

array_filter

$filtered = array_filter(
    $array1,
    function($v) use ($array2) {
        return in_array($v['service_code'], $array2);
    }
);

0
投票

由于

service_code
在数组 A 中是唯一的,因此您可以使用
array_column
来使用
service_code
重新索引数组 A。

$array_a = array_column($array_a, null, 'service_code');

然后翻转数组B,使其值成为键

$array_b = array_flip($array_b);

然后您可以使用

array_intersect_key
来获取结果。

$result = array_intersect_key($array_a, $array_b);

或者如果您愿意的话,可以在一份声明中全部列出:

$result = array_intersect_key(
    array_column($array_a, null, 'service_code'), array_flip($array_b));
© www.soinside.com 2019 - 2024. All rights reserved.