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

时间:2013-04-20 04:14:28

标签: php arrays

我有一个由以下信息组成的数组:

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

我要做的是删除重复的条目,但前提是它们紧挨着彼此。

正确的结果应如下所示:

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

我正在使用PHP,但任何类型的逻辑都可以帮助我解决这个问题。

以下是我迄今为止尝试过的一些代码:

$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,当我运行以下代码时:

$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);

,我得到了这些结果:

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', ) 

4 个答案:

答案 0 :(得分:8)

您的方法($prev_value变量)应该可以正常工作,而您不需要计数器。

您使用$counter是您的代码不起作用的原因 - if语句的前半部分始终执行,因为$counter永远不会增加;而下半部分只是比较价值观。您唯一需要做的就是将当前值与之前的值进行比较,并且仅在当前值不同时才包括当前值(或仅在它相同时将其删除)。

如果使用功能减少,则更容易看到此算法。以下是使用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);

请注意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',
)

array_reduce()方法与以下代码完全相同:

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

您可以使用相同的算法修改数组就地,而不是返回 copy ,而不是从结束 >数组:

$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);

答案 1 :(得分:2)

跟踪数组中的最后一个元素,如果刚添加它,请跳过将新元素添加到新数组中。

或者,您可以检查数组中的最后一个元素,看看它是否不是数组中的当前元素:

$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;
    }
}

答案 2 :(得分:1)

假设数组不是那么大,以至于第二个数组会导致问题,那么你描述的方法是should work。它看起来像这样吗?

$last = null;
$result = [];

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

Re:编辑:

  • $pre_value$prev_value不是一回事
  • $counter不会改变

看起来你试图以某种方式结合反制方法和“最后”方法。

答案 3 :(得分:0)

定义全局变量glob。 传递数组: if (array[i] == glob) then remove array[i] else glob = array[i]; keep array[i];