PHP多维数组与单维数据交叉

时间:2016-08-09 18:37:40

标签: php arrays multidimensional-array

需要从Array A数组中消除关键字'service_code'值在数组B上不存在。在示例中,数组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
        )
)

3 个答案:

答案 0 :(得分:2)

您的解决方案是array_filter

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

答案 1 :(得分: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 :(得分: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));