0

What I'm trying to do is find how many times an array elements repeats itself in array, push the element along with the number of repeats it has in an object and after that delete the element and all its duplicates.

At the moment I have this function :

function getDuplicates(arr) {
  let lastIndex = null;
  let obj = {};
  for ( let i = 0; i < arr.length; i++ ) {
    lastIndex = arr.lastIndexOf(arr[i]);
    obj[arr[i]] = lastIndex + 1;
    arr.splice(0, lastIndex + 1 );
  }
  console.log(obj);
}

getDuplicates([ 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6 ]);

which logs : { '1': 4, '2': 2, '3': 4, '5': 5 }

It works great for the first 3 numbers ( 1,2 and 3 ) but 4 doesnt show up, 5 is messed up and 6 doesnt show due to lastIndex +1. Am I missing something or is there a better way to do this ?

Thank you.

  • 1
    You could simply create a new array and push unique elements. –  Mar 09 '17 at 15:21
  • Did you google for an answer first? There are many solutions available on stackoverflow. – Robert Mar 09 '17 at 15:24
  • Possible duplicate of [How to count duplicate value in an array in javascript](http://stackoverflow.com/questions/19395257/how-to-count-duplicate-value-in-an-array-in-javascript) – Andreas Mar 09 '17 at 15:25

7 Answers7

0

Here's one method how to solve it.

Firstly I've removed all duplicated elements from the given array, using new Set() and then iterated over it using Array#forEach and checked with Array#filter how many times given element appears in the passed array.

function getDuplicates(arr){
  var filtered = [...new Set(arr)],
      result = {};
      filtered.forEach(function(v){
        result[v] = arr.filter(c => c == v).length;
      })
      console.log(result);
}
    
getDuplicates([ 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6 ]);

Array#reduce solution.

function getDuplicates(arr) {
  var res = arr.reduce(function(s, a) {
    s[a] = arr.filter(c => c == a).length;
    return s;
  }, {});
  console.log(res);
}

getDuplicates([1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6]);
kind user
  • 40,029
  • 7
  • 67
  • 77
  • I appreciate the anwer however I was looking for more of a "programing" solution that doesnt use js built in methods that much. – Tudor Apostol Mar 09 '17 at 18:38
  • @TudorApostol Do you want to learn JS? If so - check slowly my answer and learn. These functions are **build-in** in pure javascript. Without knowing them you won't be good in JS. So learn bro, learn! – kind user Mar 09 '17 at 18:46
0

You can simplify a lot the logic. Just an object to count and an if statement to increment values or define as 1 if it wasn't defined.

function countDuplicates(arr) {
  // Contains a pair of values an instances.
  var counting = {};
  // Iterate array: check if already counted. If yes, increment, if not define as 1.
  for (el of arr) (counting[el]) ? counting[el]++ : counting[el] = 1;
  console.log(counting);
  return counting;
}

countDuplicates([ 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6 ]);

Adding, if you also want to get the unique elements, you can just use E6 set:

var set = new Set([ 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6 ]);
nitobuendia
  • 1,228
  • 7
  • 18
  • I like the logic behind the function but I dont understand the syntax for `for (el of arr) (counting[el]) ? counting[el]++ : counting[el] = 1;`. Could you explain in basic javascript ? – Tudor Apostol Mar 09 '17 at 15:51
  • Got it, it would go something like this: `for ( let i = 0; i < arr.length; i++ ) { if ( obj[arr[i]] ) { obj[arr[i]]++; } else { obj[arr[i]] = 1; } }` – Tudor Apostol Mar 09 '17 at 15:53
  • Correct! Mixing your structure and my names :) `for (let i = 0; i < arr.length; i++) { var el = arr[i]; if (counting[el]) { counting[el]++ } else { counting[el] = 1; } }` I did it that way to make code small :) – nitobuendia Mar 09 '17 at 16:08
  • The interesting part is if I use an unsorted array it still has the same result. Can you explain why it puts the object keys in order ( from smallest to biggest ) ? – Tudor Apostol Mar 09 '17 at 16:13
  • That's because we are using numbers as the index. Hence, the order is always 0, 1, 2... Even if you convert them to string, it thinks in numbers and will order the index. However, if you try: `countDuplicates(['b', 'c', 'a']);`, it won't order them. If you want to keep them in order of appearance and keep the code simple, you could add n at the beginning of el: `for (el of arr) { el = 'n'+el; (counting[el]) ? counting[el]++ : counting[el] = 1; }` However you'd have n5 instead of 5 and so forth. – nitobuendia Mar 09 '17 at 16:40
0

It looks as if you want to COUNT duplicates, but if all you want to do is remove duplicates (As headline states), as per @ChantryCargill s suggestion:

function removeDuplicates (arr) {
   var results = [];
   for(var i = 0; i < arr.length; i++) {
      var item = arr[i];
      if(results.indexOf(item) === -1) {
         results.push(item);
      }
   }
   return results;
}

console.log(removeDuplicates([ 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6 ])); 
//[1, 2, 3, 4, 5, 6]

If you want to COUNT duplicates:

function getDuplicates(arr) {
   var results = {};
   for(var item of arr) {
      if(!results[item]) {
         results[item] = 0;
      }
      results[item]++;
   }
   return results;
}

console.log(getDuplicates([ 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6 ])); 
//{"1":4,"2":2,"3":4,"4":2,"5":3,"6":1}
Arg0n
  • 8,283
  • 2
  • 21
  • 38
0

You can simply use Array#reduce() to count the occurrences and Array#filter() to remove the duplicates

getDuplicates([1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6]);

function getDuplicates(arr) {
  var obj = arr.reduce((map, item) => (map[item] = ++map[item] || 1, map),{} );
  var withoutDup = arr.filter((item, pos) => arr.indexOf(item) == pos);

  console.log(JSON.stringify(obj));
  console.log(JSON.stringify(withoutDup));
}
Weedoze
  • 13,683
  • 1
  • 33
  • 63
0

You can count and print as you would want like this:

function getDuplicates(arr) {
    var counts = {};
    arr.forEach(function(x) { counts[x] = (counts[x] || 0)+1; });
    console.log(counts);
}
Icculus018
  • 1,018
  • 11
  • 19
0
function getDuplicates(arr) {
  let lastNum = null;
  let obj = {};
  for ( let i = 0; i < arr.length; i++ ) {
    if (arr[i] != lastNum){
      lastNum = arr[i];
      obj[arr[i]] = 1;
    }else{
      obj[arr[i]]++;
    }
  }
  console.log(obj);
}
tormich
  • 43
  • 1
  • 8
0

Try this:

function getDuplicates(){
  var numbers=Array.prototype.slice.call(arguments);
  var duplicates={};
  for(var index in numbers){
    if(numbers.indexOf(numbers[index])==index)
      continue;
    duplicates[numbers[index]]= (duplicates[numbers[index]] || 0) + 1;
  }
  return duplicates;
}

console.log(getDuplicates(1,2,3,1,1,3,4,5,6,7,8,6));
/*
prints {
  1: 2,
  3: 1,
  6: 1
}
*/
behzad besharati
  • 5,873
  • 3
  • 18
  • 22