0

I have an array with random numbers, from 1 to 6. How can I know if I have in this array two, three or four same numbers ? And what is that number ? Or if I have two numbers that they appear twice ?

array = [1, 3, 5, 5, 6];    

x = array[0];
repetitions = 0;

for (let i = 0; i < 5; i++) {
const y = array[i];

if (x === y) {
    repetitions++;
  }
} 

Should I do something like this for each element of array ?

Thank you!

Sebastian
  • 53
  • 1
  • 6

4 Answers4

4

This is a simple solution that can be provided using filter;

var array = [1,2, 3,4,4,4,4,4,4,4, 5, 5, 6,6,6];
var duplicate = [];
var newArray = array.filter((v, i) =>{ 
 if(array.indexOf(v) == i){
  return v
}else{
  duplicate.indexOf(v) == -1 ? duplicate.push(v):'';
}
})

console.log(`new array ${newArray}`);
console.log(`Duplicate values array ${duplicate}`);
Akhil Aravind
  • 5,741
  • 16
  • 35
1

There are some constraints you should clarify. For example, this code would returns the first number in the array that is duplicated:

let duplicated = [...array] // makes a copy of the array
                   .sort()  // since `sort` mutate the original
                   .find((item, index, arr) => value === arr[index + 1]);

console.log(duplicated) // 5, in your case

If there is no number duplicated, then it will return undefined.

However, maybe that is not what you want. Considering this array: [1, 3, 6, 5, 5, 6, 6, 6]. Even if there is also 6 duplicated, you will always return 5.

If you want just to know if there is at least a number duplicated, the code above will works. If you want to know all the duplicated number, and in which order they appear first in the original array, you need something different. For example:

let array = [1, 3, 6, 5, 5, 6, 6, 6];
let occurrences = array
                    .reduce((acc, value) => (acc[value]=-~acc[value], acc),{});

console.log(occurrences); // {"1": 1, "3": 1, "5": 2, "6": 4}

At this point you can decided what do you want to do with this data, e.g. you can filter out the numbers that appears in the array just once:

console.log(
  Object.fromEntries(
    Object.entries(occurrences).filter(([num, count]) => count > 1)
  )
); // {"5": 2, "6": 4}

etc.

UPDATE (see comments): Object.fromEntries is a method recently introduced, in case having a filtered object with all the occurrences is the goal, in this context could be easily replaced by a function like this:

const fromEntries = entries => 
  entries.reduce((acc, [key, value]) => (acc[key] = value, acc), {});
ZER0
  • 24,846
  • 5
  • 51
  • 54
  • Yep, I think this is the best solution ! Bravo ! – Sebastian Feb 07 '19 at 18:33
  • But why I receive "Property 'fromEntries' does not exist on type 'ObjectConstructor'" ? – Sebastian Feb 07 '19 at 18:42
  • It might be very possible that the engine you’re using do not support `Object.fromEntries` yet, it’s very recent: you can either use a 3rd party polyfill, a transpiler such Babel, or recreate the object yourself in a similar way I did with the first `reduce`. – ZER0 Feb 07 '19 at 18:51
0

You check if the value in array exists more than 2 times by compare indexOf and lastIndexOf the value

function duplicates(arr){
  let result = []
  arr.forEach(item => {
    if(arr.indexOf(item) !== arr.lastIndexOf(item)){
      result.push(item)
    }
  })
  return [... new Set(result)];
}
console.log(duplicates([1,2,3,5,5,6,6,6]));
Maheer Ali
  • 35,834
  • 5
  • 42
  • 73
0

You could take a Map and count all occurences of the values.

The result is an array where the first element is the value and the second is the count of the value.

var array = [1, 3, 5, 5, 6],
    counts = Array.from(array.reduce((m, v) => m.set(v, (m.get(v) || 0) + 1), new Map));
    
console.log(counts);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392