为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用黑名单数组删除值,然后减少剩余值以消除间隙?

如何使用黑名单数组删除值,然后减少剩余值以消除间隙?

PHP
ABOUTYOU 2023-07-21 15:57:37
这个问题基本上是我之前问题的延伸:如何减去数组的值但仍处于位置我有一个数组的输入数组。每个子数组中的值始终由0从无间隙开始的值组成,值递增 1。但是,这些值不一定按顺序排列,并且我需要在执行所需逻辑时保留此顺序。接下来,我有一个希望从所有子数组中删除的值黑名单。必须删除黑名单数组中存在的任何原始子数组值。数组的示例输入数组:$arrays = [     [0, 3, 10, 5, 6, 9, 2, 7, 1, 4, 8, 11],     [0, 1, 2, 3],     [0, 5, 2, 4, 3, 1],     [0, 1, 3, 2] ];黑名单数组示例:$deletes = [3, 5];我想要的输出是:[     [0, 8, 4, 7, 2, 5, 1, 3, 6, 9],     [0, 1, 2],     [0, 2, 3, 1],     [0, 1, 2], ]自从我删除数字以来,所有大于的剩余值都3减少了1,并且大于的值都5减少了。22如果给定子数组中的所有数字都小于黑名单数组中的所有数字,则不需要对该子数组进行任何更改。我在这里尝试编码https://3v4l.org/lX2MP,但在返回它们的值时我陷入困境。所有数组值都合并在一起。
查看完整描述

2 回答

?
尚方宝剑之说

TA贡献1788条经验 获得超4个赞

我将稍微改变你的第二个、第三个和第四个子数组,以更好地演示该行为。

利用我对上一个问题的回答中的一项技术,我实际上只是将代码逻辑包装在一个附加循环中array_map()

array_diff()用于立即销毁输入数组中与删除值匹配的任何值。然后array_reduce()使用输入数组的剩余值来迭代并减少任何生成的整数以消除间隙。

里面array_reduce(),你会看到$value > $item。此比较将返回trueor false。当布尔值用作数字时,true变为1false变为0。基本上,我根据每个值与给定的比较来减去01减去。$value$deletes$value

作为一个具体例子,当处理时1010大于3,因此变为9,并且10大于,5因此9变为8

这一切都是在不需要预先排序数据的情况下完成的。

代码:(演示

$arrays = [[0, 3, 10, 5, 6, 9, 2, 7, 1, 4, 8, 11], [0, 1, 2, 3], [0, 5, 2, 4, 3, 1], [0, 1, 3, 2]];

$deletes = [3, 5];


var_export(

    array_map(

        function($array) use ($deletes) {

            $result = [];

            foreach (array_diff($array, $deletes) as $value) {

                $result[] = array_reduce(

                    $deletes,

                    function ($carry, $item) use ($value) {

                        return $carry - ($value > $item);

                    },

                    $value

                );

            }

            return $result;

        },

        $arrays

    )

);

这是一种行为方式相同但不太依赖函数式编程的替代方案:(演示


foreach ($arrays as $index => $array) {

    $filtered = array_diff($array, $deletes);  // destroy blacked values

    foreach ($filtered as $value) {

        $originalValue = $value;

        foreach ($deletes as $delete) {

            $value -= $originalValue > $delete; // reduce to eliminate gaps

        }

        $result[$index][] = $value;

    }

}


var_export($result);

输出(对于任一片段):


array (

  0 => 

  array (

    0 => 0,

    1 => 8,

    2 => 4,

    3 => 7,

    4 => 2,

    5 => 5,

    6 => 1,

    7 => 3,

    8 => 6,

    9 => 9,

  ),

  1 => 

  array (

    0 => 0,

    1 => 1,

    2 => 2,

  ),

  2 => 

  array (

    0 => 0,

    1 => 2,

    2 => 3,

    3 => 1,

  ),

  3 => 

  array (

    0 => 0,

    1 => 1,

    2 => 2,

  ),

)


查看完整回答
反对 回复 2023-07-21
?
阿波罗的战车

TA贡献1862条经验 获得超6个赞

要从数组中删除数字并从原始数组中的当前数字中减去小于该数字的计数selectedDeletedNumbers,您可以:

  • 对数组进行排序selectedDeletedNumbers

  • 迭代原始数组并使用它binary search来获取小于原始数组中当前数字的数字计数,然后将其减去。

  • 如果当前编号存在于 中selectedDeletedNumbers,则取消设置它们。

  • 对每个单独的子数组应用上述操作。

片段:

<?php


function subtract(&$arr,$selectedDeletedNumbers){ // pass by reference to edit the same copy of the array

    foreach($arr as $index => $val){

        $low = 0;$high = count($selectedDeletedNumbers) - 1;

        $equal_found = false;

        while($low <= $high){

            $mid = intval(($low + $high) / 2);

            if($selectedDeletedNumbers[$mid] > $val){

                $high = $mid - 1;

            }else if($selectedDeletedNumbers[$mid] < $val){

                $low = $mid + 1;

            }else{

                $equal_found = true;

                unset($arr[$index]); // if equal value, delete it as it your need

                break;

            }

        }

    

        if(!$equal_found){

            $arr[$index] -= $low; // delete the offset till where it is greater among your $selectedDeletedNumbers

        }

    }

}


$selectedDeletedNumbers = [3,5];

sort($selectedDeletedNumbers); // sort to be apply binary search later

$arr = [[0, 3, 10, 5, 6, 9, 2, 7, 1, 4, 8, 11], [0, 1], [0, 1], [0, 1]];


foreach($arr as &$val){ // pass by reference to edit the same copy of the array

    subtract($val,$selectedDeletedNumbers); 

}


print_r($arr);

演示: https: //3v4l.org/RMh5U

如果您想按顺序重新索引数字,请array_values()最后对每个单独的子数组执行一个操作。


查看完整回答
反对 回复 2023-07-21
  • 2 回答
  • 0 关注
  • 86 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信