1

I need to delete occurrences of an element if it occurs more than n times.

For example, there is this array:

[20,37,20,21]

And the output should be:

[20,37,21]

I thought one way of solving this could be with the splice method

First I sort the array it order to make it like this:

[20,20,37,21]

Then I check if the current element is not equal to the next and split the array into chunks, so it should look like:

[20, 20],[37],[21]

Later I can edit the chunk longer than 1 and join it all again.

This is what the code looks like in my head but didn't work in real life

var array = [20, 37, 20, 21];
var chunk = [];
for(i = 0; i < array.length; i++) {
    if(array[i] !== array[i + 1]) {
        var index = array.indexOf(array[i]);
        chunk.push = array.splice(0, index) // cut from zero to last duplicate element
    } else
        var index2 = a.indexOf(a[i]);
    chunk.push(a.splice(0, index));
}

with this code the output is

[[], [20, 20]]

I think It's something in the 'else' but can't figure it out what to fix.

cetaphil
  • 65
  • 1
  • 6
  • Possible duplicate of [How to get distinct values from an array of objects in JavaScript?](http://stackoverflow.com/q/15125920/1026459) – Travis J Oct 27 '16 at 22:40

4 Answers4

0

As the logic you want to achieve is to delete n occurrences of element in an array, your code could be as follow:

var array = [1, 1, 3, 3, 7, 2, 2, 2, 2];
var n = 2;

var removeMultipleOccurences = function(array, n) {
  var filteredArray = [];
  var counts = {};
  for(var i = 0; i < array.length; i++) {
    var x = array[i];
    counts[x] = counts[x] ? counts[x] + 1 : 1;
    if (counts[x] <= n) filteredArray.push(array[i])
  }
  return filteredArray;
}

console.log(removeMultipleOccurences(array, n));
Basim Hennawi
  • 2,651
  • 3
  • 19
  • 31
  • Maybe I didn't explain it good. If the array is [20, 20, 20, 20, 21,21, 37] and 'n' is 3 it should be [20,20,20,21,21,37]. I don't see how filter can work in this case – cetaphil Oct 27 '16 at 23:14
  • @cetaphil If you are trying to remove element at index 3 a loop is not necessary. You can use `var array = [20, 20, 20, 20, 21,21, 37]; array.splice(n, 1)`, where n is `3` – guest271314 Oct 27 '16 at 23:23
  • 'n' should be the number of times a item can repeat itself, I need the loop to look for duplicates items in the whole array. If I use it as index at 3 something like this would happen [1,1,3,3,7,2,2,2,2] => [1, 1, 3, 7, 2, 2, 2, 2]. In this case '2' repeat more than 'n' times. – cetaphil Oct 27 '16 at 23:39
  • @cetaphil Please check the edited code snipped to meet your needed logic. – Basim Hennawi Oct 28 '16 at 00:14
0

You can use Array.prototype.reduce(), Array.prototype.filter() to check if n previous elements are the same as current element

let cull = (arr, n) => arr.reduce((res, curr) => [...res
           , res.filter(v => v === curr).length === n 
           ? !1 : curr].filter(Boolean), []);

let arrays = [[20,37,20,21], [1,1,3,3,7,2,2,2,2]];
              
let cullone = cull(arrays[0], 1);

let cullthree = cull(arrays[1], 3);

console.log(cullone // [20, 37, 21]
            , cullthree // [1, 1, 3, 3, 7, 2, 2, 2]
           );
guest271314
  • 1
  • 15
  • 104
  • 177
0

I came up with this one, based on array filter checking repeated values up to a limit, but I can see @Basim's function does the same.

function removeDuplicatesAbove(arr, max) {
    if (max > arr.length) {max = arr.length;}
    if (!max) {return arr;}
    return arr.filter(function (v, i) {
        var under = true, base = -1;
        for (var n = 0; n < max; n++) {
            base = arr.indexOf(v, base+1); if (base == -1) {break;}
        }
        if (base != -1 && base < i) {under = false;}
        return under;
    });
}

var exampleArray = [20, 37, 20, 20, 20, 37, 22, 37, 20, 21, 37];

console.log(removeDuplicatesAbove(exampleArray, 3)); // [20, 37, 20, 20, 37, 22, 37, 21]
Javier Rey
  • 1,539
  • 17
  • 27
0

Always when you use splice() you truncate the array. Truncate the array with the length of same values from the start with the help of lastIndexOf(). It always starts from 0.

[ 1, 1, 1, 2, 2, 2, 3, 4, 4, 5 ] // splice(0, 3)
[ 2, 2, 2, 3, 4, 4, 5 ] // splice(0, 3)
[ 3, 4, 4, 5 ] // splice(0, 1)
[ 4, 4, 5 ] // splice(0, 2)
[ 5 ] // splice(0, 1)

Do this as long as the array length is greater than 0.

var arr = [1, 1, 1, 2, 2, 2, 3, 4, 4, 5];
var res = [];

while (arr.length > 0) {
  var n = arr[0];
  var last = arr.lastIndexOf(n) + 1;
  res.push(n);
  arr.splice(0, last);
}

console.log(res);