按另一个二维数组中的多列过滤二维数组,该数组不包含第一个数组中的所有列

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

我有以下两个数组:

$a = [
    ['code' => '123', 'name' => 'ABC',],
    ['code' => '456', 'name' => 'XYZ',],
];

$b = [
    ['code' => '123', 'name' => 'ABC', 'price' => '34'],
    ['code' => '456', 'name' => 'PQR', 'price' => '56'],
    ['code' => '456', 'name' => 'XYZ', 'price' => '90'],
];

我想创建第三个数组,其中代码和名称的组合匹配,如下所示:

$c = [
    ['code' => '123', 'name' => 'ABC', 'price' => '34'],
    ['code' => '456', 'name' => 'XYZ', 'price' => '90'],
]

我不想保留

$b
的第二行,因为该行中的代码和名称的组合与数组中的行不匹配
$a

php arrays multidimensional-array filtering array-intersect
2个回答
1
投票

您的数据结构没有构建得很好,无法满足所需的比较。如果两个数组都有“复合键”而不是索引,那就更容易了。我的意思是,如果数组中的行看起来像

'123_ABC' => ['code' => '123', 'name' => 'ABC',]
那么进行直接基于键的比较将是一件轻而易举的事。

使用您拥有的资源,并为了减少数组上的总迭代次数,我建议在找到匹配项后立即在内部循环中进行早期中断的嵌套循环。

代码:(演示

$whiteList = [
    ['code' => '123', 'name' => 'ABC',],
    ['code' => '456', 'name' => 'XYZ',],
];

$pricedList = [
    ['code' => '123', 'name' => 'ABC', 'price' => '34'],
    ['code' => '456', 'name' => 'PQR', 'price' => '56'],
    ['code' => '456', 'name' => 'XYZ', 'price' => '90'],
    ['code' => '456', 'name' => 'GHI', 'price' => '70'],
];

$result = [];
foreach ($pricedList as $pricedRow) {
    foreach ($whiteList as $whiteRow) {
        if ($whiteRow['code'] === $pricedRow['code'] && $whiteRow['name'] === $pricedRow['name']) {
            $result[] = $pricedRow;
            continue 2;  // no reason to keep iterating inner loop after match is found
        }
    }
}
var_export($result);

或者更优雅地,对白名单数组的每一行使用

array_intersect_assoc()
。 (演示)

$result = [];
foreach ($pricedList as $pricedRow) {
    foreach ($whiteList as $whiteRow) {
        if ($whiteRow === array_intersect_assoc($whiteRow, $pricedRow)) {
            $result[] = $pricedRow;
            continue 2;  // no reason to keep iterating inner loop after match is found
        }
    }
}
var_export($result);

输出(来自任一片段):

array (
  0 => 
  array (
    'code' => '123',
    'name' => 'ABC',
    'price' => '34',
  ),
  1 => 
  array (
    'code' => '456',
    'name' => 'XYZ',
    'price' => '90',
  ),
)

0
投票

通过在

array_uintersect()
内部进行全行比较之前无条件清除潜在价格元素,您可以通过不包含价格的数组来过滤包含价格数据的数组。

代码:(演示

var_export(
    array_uintersect(
        $pricedList,
        $whiteList,
        function($a, $b) {
            unset($a['price'], $b['price']);
            return $a <=> $b;
        }
    )
);
© www.soinside.com 2019 - 2024. All rights reserved.