简体   繁体   English

仅当它们彼此相邻时才删除数组中的元素

[英]Deleting Elements In An Array Only When They Are Next To Each Other

I have an array that is composed of information that looks like the following: 我有一个数组,该数组由如下所示的信息组成:

['Jay', 'Jay', 'Jay', 'Spiders', 'Dogs', 'Cats', 'John', 'John', 'John', 'Dogs', 'Cows', 'Snakes']

What I'm trying to do is remove duplicate entries but only if they occur right next to each other. 我想做的是删除重复的条目,但前提是它们彼此相邻。

The correct result should look like the following: 正确的结果应如下所示:

['Jay', 'Spiders', 'Dogs', 'Cats', 'John', 'Dogs', 'Cows', 'Snakes']

I'm using PHP but any kind of logic would be able to help me out with this problem. 我正在使用PHP,但是任何一种逻辑都可以帮助我解决这个问题。

Here is some code I've tried so far: 这是到目前为止我尝试过的一些代码:

$clean_pull = array();
$counter = 0;
$prev_value = NULL;

foreach($pull_list as $value) {
    if ($counter == 0) {
        $prev_value = $value;
        $clean_pull[] = $value;
    }
    else {
        if ($value != $pre_value) {
            $pre_value = value;
        }
    }
    echo $value . '<br>';
}

Francis, when I run the following code: 弗朗西斯,当我运行以下代码时:

$lastval = end($pull_list);
for ($i=count($pull_list)-2; $i >= 0; $i--){
    $thisval = $pull_list[$i];
    if ($thisval===$lastval) {
        unset($pull_list[$i]);
    }
    $lastval = $thisval;
}
# optional: reindex the array:
array_splice($pull_list, 0, 0);

var_export($pull_list);

, I get these results: ,我得到以下结果:

array ( 0 => 'NJ Lefler', 1 => 'Deadpool', 2 => 'NJ Lefler', 3 => 'Captain Universe: The Hero Who Could Be You', 4 => 'NJ Lefler', 5 => 'The Movement', 6 => 'NJ Lefler', 7 => 'The Dream Merchant', 8 => 'Nolan Lefler', 9 => 'Deadpool', 10 => 'Nolan Lefler', 11 => 'Captain Universe: The Hero Who Could Be You', 12 => 'Nolan Lefler', 13 => 'The Movement', 14 => 'Tom Smith', 15 => 'Deadpool', 16 => 'Tom Smith', 17 => 'Captain Universe: The Hero Who Could Be You', ) 

Your approach (a $prev_value variable) should work fine and you don't need a counter. 您的方法( $prev_value变量)应该可以正常工作,并且您不需要计数器。

Your use of $counter is why your code doesn't work--the first half of the if statement is always executed because $counter is never incremented; 使用$counter就是代码无法正常工作的原因if语句的前半部分总是执行,因为$counter不会递增; and the second half just compares values. 下半部分只是比较值。 The only thing you need to do is compare the current value with the previous value and include the current value only if it differs (or remove it only if it's the same). 您唯一需要做的就是将当前值与先前的值进行比较,并仅在当前值不同时才包括它(或在相同时将其删除)。

It's much easier to see this algorithm if you use functional reduction. 如果使用功能约简,则更容易看到此算法。 Here is an example using array_reduce : 这是使用array_reduce的示例:

$a = array('Jay', 'Jay', 'Jay', 'Spiders', 'Dogs', 'Cats', 'John', 'John', 'John', 'Dogs', 'Cows', 'Snakes');

$na = array_reduce($a, function($acc, $item){
    if (end($acc)!==$item) {
        $acc[] = $item;
    }
    return $acc;
}, array());

var_export($na);

Note this comparison of var_export($a) (your original array) and var_export($na) (the result produced by the code): 请注意var_export($a) (原始数组)和var_export($na) (由代码产生的结果)的比较:

$a = array (            $na = array (    
  0 => 'Jay',             0 => 'Jay',    
  1 => 'Jay',             1 => 'Spiders',
  2 => 'Jay',             2 => 'Dogs',   
  3 => 'Spiders',         3 => 'Cats',   
  4 => 'Dogs',            4 => 'John',   
  5 => 'Cats',            5 => 'Dogs',   
  6 => 'John',            6 => 'Cows',   
  7 => 'John',            7 => 'Snakes', 
  8 => 'John',          )                
  9 => 'Dogs',
  10 => 'Cows',
  11 => 'Snakes',
)

The array_reduce() method does exactly the same thing as the following code: array_reduce()方法与以下代码完全相同:

$na = array();
foreach ($a as $item) {
    if (end($na)!==$item) {
        $na[] = $item;
    }
}

Instead of returning a copy of an array, you can also modify the array in-place using the same algorithm but starting from the end of the array: 除了返回数组的副本之外 ,您还可以使用相同的算法从数组末尾开始就地修改数组:

$lastval = end($a);
for ($i=count($a)-2; $i >= 0; $i--){
    $thisval = $a[$i];
    if ($thisval===$lastval) {
        unset($a[$i]);
    }
    $lastval = $thisval;
}
# optional: reindex the array:
array_splice($a, 0, 0);

var_export($a);

Keep track of the last element in the array, and skip adding the next element to your new array if you just added it. 跟踪数组中的最后一个元素,如果刚刚添加了新元素,请跳过将下一个元素添加到新数组中的操作。

Or, you can just check the last element in the array, and see if it's not the current element in your array: 或者,您可以只检查数组中的最后一个元素,然后查看它是否不是数组中的当前元素:

$array = ['Jay', 'Jay', 'Jay', 'Spiders', 'Dogs', 'Cats', 'John', 'John', 'John', 'Dogs', 'Cows', 'Snakes'];
$new = array( array_shift( $array));
foreach( $array as $el) {
    if( !($new[count($new) - 1] === $el)) {
        $new[] = $el;
    }
}

Assuming the array isn't so large that having a second one will cause a problem, the approach you described should work . 假设数组不是很大,以至于第二个数组会引起问题,那么您描述的方法应该可以工作 Does it look like this? 看起来像这样吗?

$last = null;
$result = [];

foreach($arr as $item)
    if($item !== $last)
        $result[] = $last = $item;

Re: edit: 回复:编辑:

  • $pre_value and $prev_value aren't the same thing $pre_value$prev_value不是同一回事
  • $counter doesn't change $counter不变

It looks like you tried to combine a counter approach and a "last" approach somehow. 看来您试图以某种方式将反制方法和“最后”方法结合在一起。

Define a global variable glob . 定义一个全局变量glob pass the array: if (array[i] == glob) then remove array[i] else glob = array[i]; keep array[i]; 通过数组: if (array[i] == glob) then remove array[i] else glob = array[i]; keep array[i]; else glob = array[i]; keep array[i];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM