1

我有一个数组,它由如下所示的信息组成:

['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>';
}

弗朗西斯,当我运行以下代码时:

$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

4 回答 4

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

除了返回数组的副本,您还可以使用相同的算法就地修改数组,但从数组的末尾开始:

$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);
于 2013-04-20T04:26:49.843 回答
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;
    }
}
于 2013-04-20T04:26:24.683 回答
1

假设数组不是太大以至于有第二个会导致问题,那么您描述的方法应该可以工作。它看起来像这样吗?

$last = null;
$result = [];

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

回复:编辑:

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

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

于 2013-04-20T04:26:41.153 回答
0

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

于 2013-04-20T04:19:45.133 回答