在PHP中删除foreach中数组中的元素(高级)

时间:2017-01-08 18:25:11

标签: php arrays

这是我的问题: 我有一个id' s($ arr)的数组,我以三个为一组进行切片。接下来,我有一个包含其他id($ otherIds)的数组,我想与主数组($ arr)进行比较,如果某些id是相同的 - 它们应该从其余部分删除$ arr's chunk。

F.e。我有$arr = array(1, 2, 3, 4, 5, 6, 7, 8)$otherIds = array(5, 7)。我将$ arr切换到三个元素的块中,然后在foreach中循环$ arr并将它们与$ otherIds进行比较,因此在第一次迭代中 - 代码应该看到$ otherIds' 5'和' 7'存在于$ arr的下一个块中,并删除它们。 我的输出应该是:

  • 第一次迭代 - 数组(1,2,3)
  • 第二次迭代 - 应该删除数组(4,6) - 5
  • 第3次迭代 - 应该删除数组(8) - 7

$otherIds在每次迭代中都可以不同(它们来自数据库),但为了简化它,我将使用常量值。

这是我的代码:

$arr = array(15, 10, 12, 17, 21, 13, 15, 25, 7, 18, 4, 1, 5, 2);

$chunks = array_chunk($arr, 3);
$ids = array();
foreach ($chunks as $k => $v) {
    $otherIds = array(6, 7, 22, 31, 44, 9, 17);
    $ids = $v;

    foreach ($chunks as $key => $val) {
        if ($key <= $k) continue;
        foreach ($chunks[$key] as $g => $ch) {
            foreach ($otherIds as $o) {
                if ($ch['id'] == $o) {
                    $ids[] = $o;
                    unset($chunks[$key][$g]);
                }
            }
        }
    }
}

正如您所看到的,我使用了许多预言,但我看不到更好的解决方案...... 此外,主foreach的每个下一次迭代都应该(如上所述)由$ otherIds中的已删除元素缩短 - 我这段代码没有这样做。

如何实现呢?有更简单/更好/更有效的解决方案吗? 我再说一遍:主要目标是在main foreach的每次迭代中检查$ otherIds,并从$ arr中删除其他块中的相同元素。

2 个答案:

答案 0 :(得分:0)

尝试array_diff()

$arr = array(15, 10, 12, 17, 21, 13, 15, 25, 7, 18, 4, 1, 5, 2);
$chunks = array_chunk($arr, 3);

// Build the filtered list into $output
$output = array();
foreach ($chunks as $k => $v) {
    $otherIds = array(6, 7, 22, 31, 44, 9, 17);
    // array_diff() returns the list of values from $v that are not in $otherIds
    $output[$k] = array_diff($v, $otherIds);
}

// Investigate the result
print_r($output);

更新

我重新阅读了这个问题,我想我最终理解了逻辑(未在示例数据中描述)。在每次迭代时,它会获取一组要忽略的新ID,并从当前块开始将其从所有块中删除。

更新的代码是:

$arr = array(15, 10, 12, 17, 21, 13, 15, 25, 7, 18, 4, 1, 5, 2);
$chunks = array_chunk($arr, 3);

// $chunks is numerically indexed; we can use for() to iterate it 
// (avoid assigning to $v a value that is never used)
$count = count($chunks);
for ($k = 0; $k < $count; $k ++) {
    $otherIds = array(6, 7, 22, 31, 44, 9, 17);

    // $chunks is numerically indexed; start with key `$k` to iterate it
    for ($key = $k; $key < $count; $key ++) {
        // remove the values from $otherId present in the chunk
        $chunks[$key] = array_diff($chunks[$key], $otherIds);
    }
}

答案 1 :(得分:0)

修改数组时,你在foreach循环中进行迭代,你搞乱了数组中的内部指针,事情变得混乱。

在拿起三胞胎的同时制作副本,不要unset()也不要修改原始阵列。由于PHP中的写时复制功能,即使元素是大结构而不仅仅是数字,副本也会快速且经济高效。