user123
user123

Reputation: 443

remove successive duplicates in array

I'm working on a function which removes the duplicates in an array. The catch on this function is if the consecutive duplicates are less than 5 it will remain and 5 above will become a single number.

My problem is cant figure out the logic.

hope you can help me.

thanks.

Sample code

function removeDuplicates($array){
        $result = array();
        $lastVal = null;
        $temp_array = array();
        foreach ($array as $key => $value) {
            # code...
            if($value != $firstVal){

                $result[] = $value;   

            }else{

                $temp_array[] = $value;

            }

            $lastVal = $value;

        }

        return $result;

    }

sample

$array = array(1,2,4,1,1,1,1,0,8,7,2,0,0,8,8,8,8,8,8,8,2,4,1,5);

expected result

[1,2,4,1,1,1,1,0,8,7,2,0,0,8,2,4,1,5]

Upvotes: 5

Views: 258

Answers (4)

MorganFreeFarm
MorganFreeFarm

Reputation: 3723

Here:

    <?php

    $array = array(1,2,4,1,1,1,1,0,8,7,2,0,0,8,8,8,8,8,8,8,2,4,1,5);
    $test = removeDuplicates($array);
    echo '<pre>';
    var_dump($test);


function removeDuplicates($array){
    $result = [];
    $count = 1;

    for ($i = 1; $i <= count($array)-1; $i++) {
        if ($array[$i] == $array[$i - 1]) {
            $count++;
        } else {
            if ($count >= 5) {
                array_splice($array, $i-$count, $count-1);
            }
            $count = 1;
        }
    }

    return $array;

}

Output:

array(18) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(4)
  [3]=>
  int(1)
  [4]=>
  int(1)
  [5]=>
  int(1)
  [6]=>
  int(1)
  [7]=>
  int(0)
  [8]=>
  int(8)
  [9]=>
  int(7)
  [10]=>
  int(2)
  [11]=>
  int(0)
  [12]=>
  int(0)
  [13]=>
  int(8)
  [14]=>
  int(2)
  [15]=>
  int(4)
  [16]=>
  int(1)
  [17]=>
  int(5)
}

Upvotes: 3

nice_dev
nice_dev

Reputation: 17805

<?php

function removeDuplicates($array){
    $freq = 5;

    $result = [];
    $size = count($array);

    $counts = [];
    for($i=0;$i<$size;++$i) $counts[] = 0;

    $counts[$size-1] = 1;

    for($i=$size-2;$i>=0;--$i){
        $counts[$i] = 1;
        if($array[$i] === $array[$i+1]) $counts[$i] = $counts[$i+1] + 1;            
    }

    for($i=0;$i<$size;++$i){
        $result[] = $array[$i];
        if($counts[$i] >= $freq){
            $i += $counts[$i] - 1; 
        }
    }

    return $result;
}

$array = array(1,2,4,1,1,1,1,0,8,7,2,0,0,8,8,8,8,8,8,8,2,4,1,5);

print_r(removeDuplicates($array));

Demo: https://3v4l.org/mvjOq

  • Above is an O(n) algorithm(with O(n) extra space) where we first pre-compute how much count does the current number have consecutively.

  • Now, when we iterate again, we check if current array's number has a count value >= frequency. Here, frequency is 5.

  • If the count is less than frequency, iterate usually. Otherwise we jump directly to the next worthy number to process with the help of frequency stored in $count[$i] for that particular number. This would work even when your frequency to be opted for is 1000 or more.

Upvotes: 3

Ashad Bappy
Ashad Bappy

Reputation: 1

It should something like this

$array = array("1", "2", "3", "4", "5", "4", "2", "1");

$result = array_unique($array);

Upvotes: -2

as an option

removeDuplicates(array(1,2,4,1,1,1,1,0,8,7,2,0,0,8,8,8,8,8,8,8,2,4,1,5));

function removeDuplicates($arr){
    $count_duplicates = 0;
    foreach ($arr as $key => $item){
        if($item == $arr[$key+1]){
            $count_duplicates++;
        }else{
            if($count_duplicates >= 5){
                for($i = 0; $i < $count_duplicates; $i++){
                    unset($arr[$key-$i]);
                }
            }
            $count_duplicates = 0;
        }
    }
    return $arr;
}

Upvotes: 0

Related Questions