12

I have an array like var arr = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4, 5, 5, 5]; I really want the output to be [5,2,9,4,5]. My logic for this was:

  • Go through all the element one by one.
  • If the element is the same as the prev element, count the element and do something like newA = arr.slice(i, count)
  • New array should be filled with just identical elements.
  • For my example input, the first 3 elements are identical so newA will be like arr.slice(0, 3) and newB will be arr.slice(3,5) and so on.

I tried to turn this into the following code:

function identical(array){
    var count = 0;
    for(var i = 0; i < array.length -1; i++){
        if(array[i] == array[i + 1]){
            count++;
            // temp = array.slice(i)
        }else{
            count == 0;
        }
    }
    console.log(count);
}
identical(arr);

I am having problems figuring out how to output an element that represents a group of element that are identical in an array. If the element isn't identical it should be outputted in the order that it is in in the original array.

Patrick M
  • 10,547
  • 9
  • 68
  • 101
jack blank
  • 5,073
  • 7
  • 41
  • 73
  • Can you maybe give a http://www.jsfiddle.net? – Michelangelo Jun 08 '15 at 18:51
  • 1
    Why are you slicing the array? – thefourtheye Jun 08 '15 at 18:51
  • What do you mean with "output an element that represents a group of element"? You can easily remove repetitions but what does this have to do with "output"? Maybe you want a data structure that keeps track of the repetitions albeit the original array is reduced? – pid Jun 08 '15 at 18:53
  • so what expected output:`[5,2,9,4,5]` or `[[5, 5, 5], [2, 2, 2, 2, 2], 9, 4, [5, 5, 5]]` or something else? – Grundy Jun 08 '15 at 18:55
  • @Grundy [5,2,9,4,5]... i wanted to slice because i didnt know how else to split up the sections that are identical so i could get the number – jack blank Jun 08 '15 at 18:57
  • I like these answers. I'm going to need some time to go over them before i accept one. Thanks guys – jack blank Jun 08 '15 at 19:08

5 Answers5

36

Using array.filter() you can check if each element is the same as the one before it.

Something like this:

var a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4, 5, 5, 5];

var b = a.filter(function(item, pos, arr){
  // Always keep the 0th element as there is nothing before it
  // Then check if each element is different than the one before it
  return pos === 0 || item !== arr[pos-1];
});

document.getElementById('result').innerHTML = b.join(', ');
<p id="result"></p>
gen_Eric
  • 223,194
  • 41
  • 299
  • 337
  • im not sure about the return statement. your setting the index `pos` on the left side to 0. On the right side your checking to see if the item is not equal to arr[0-1] for the first iteration then iterating through the array [1-1], [2-1] etc. with the filter method? this is a lil too advanced for me. i think arr[-1] is undefined. – jack blank Jun 08 '15 at 20:12
  • 2
    @user2537537: I'm not setting anything. `pos === 0` is a comparison. It's checking if `pos` is equal to `0`. If it is, it adds it to the new array. (It assumes `0` should be in the new array because `arr[-1]` is undefined.) If `pos` is greater than `0`, then the other side of the `OR` (`||`) statement is evaluated. `item !== arr[pos-1]` checks if the current item in the array is different from the previous one. If it is, then it's added to the new array, otherwise it's skipped. – gen_Eric Jun 08 '15 at 20:42
  • `a.filter()` iterates over each element and runs the callback. It passes the callback function the value of the element, its index (and the entire array) as the parameters to the callback. – gen_Eric Jun 08 '15 at 20:45
4

if you are looking purely by algorithm without using any function

var arr = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4, 5, 5, 5];

    function identical(array){

        var newArray = [];
        newArray.push(array[0]);
        for(var i = 0; i < array.length -1; i++) {
            if(array[i] != array[i + 1]) {
                newArray.push(array[i + 1]);
            }
        }
        console.log(newArray);
    }
    identical(arr);

Fiddle;

malisit
  • 1,253
  • 2
  • 17
  • 36
Amit.rk3
  • 2,417
  • 2
  • 10
  • 16
3

Yet another way with reduce

var arr = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4, 5, 5, 5];

var result = arr.reduce(function(acc, cur) {
  if (acc.prev !== cur) {
    acc.result.push(cur);
    acc.prev = cur;
  }
  return acc;
}, {
  result: []
}).result;


document.getElementById('d').innerHTML = JSON.stringify(result);
<div id="d"></div>
Grundy
  • 13,356
  • 3
  • 35
  • 55
1

A bit hackey, but, hell, I like it.

var arr = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4, 5, 5, 5];
var arr2 = arr.join().replace(/(.),(?=\1)/g, '').split(',');

Gives you

[5,2,9,4,5]

Admittedly this will fall down if you're using sub-strings of more than one character, but as long as that's not the case, this should work fine.

Mitya
  • 33,629
  • 9
  • 60
  • 107
  • Maybe if you replace `(.)` with `(^,)+` (match all but a comma) it should also work with multi-character matches and sub-strings. Don't really know until I test it but I'm too lazy right now :) – pid Jun 08 '15 at 19:01
  • Gotta love unexplained downvotes. @pid - maybe you're right, I'm a bit lazy to check. – Mitya Jun 09 '15 at 12:25
  • Regex is the wrong tool for the job. Your one liner is by far the hardest to understand. In this simple example, it seems to be only [about half as fast](http://jsperf.com/array-filter-vs-regex) - with the askers shorter 13 element input array, it still clocks in at 75% slower than the most simple array scan posted by @Amit.rk3. Tested with Firefox 38 and Chrome 43; curiously, the filter is slower than the regex on Firefox, but the forloop consistently beats all others by a wide margin. – Patrick M Jun 10 '15 at 16:44
  • 1
    Perhaps you missed my proviso: "A bit hackey, but, hell, I like it." I never said it was the optimum solution, merely "a" solution, so chill. – Mitya Jun 18 '15 at 14:50
-2

Try this:

var a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4, 5, 5, 5];

uniqueArray = a.filter(function(item, pos) {
return a.indexOf(item) == pos;
});

See Remove Duplicates from JavaScript Array

Community
  • 1
  • 1
brroshan
  • 1,640
  • 17
  • 19
  • 3
    Not quite. This will result in `[5, 2, 9, 4]`. The OP wanted to only remove "local" duplicates to get a result of `[5, 2, 9, 4, 5]`. – gen_Eric Jun 08 '15 at 18:54