Find duplicate pairs in an array

Viewed 1698

I have an array a = [1,1,1,2,2,3,3,3,4,4,4,6,6,6,7,7] I want to fetch all the duplicate pair in this array list. Since there are pairs of 2 and 7 the output should be -

Output: [2, 7]

I tried writing my own logic but I am very weak in that area. Can somebody help?

function getDuplicateArrayElements(arr){
let sorted_arr = arr.slice().sort();
let results = [];

for (let i = 0; i < sorted_arr.length; i++) {
    let matchingElementCount = 1;

    for (let j = i + 1; j < sorted_arr.length - i; j++) {
        if (sorted_arr[j] === sorted_arr[i]) {
            ++matchingElementCount;          
        } else {
            
            if(matchingElementCount % 2 === 0) {
                results.push(sorted_arr[i]);
            }
            i = j - 1;
            break;

        }
    }
}
return results; } var a = [1,1,1,2,2,3,3,3,4,6,6,6,7,7]; var duplicateValues= getDuplicateArrayElements(a);
10 Answers

You can achieve your result by using reduce and forEach.

const arr = [1,1,1,1,2,2,3,3,3,4,4,4,6,6,6,7,7];

// Generate a hashmap from the given array for counting the frequency.
const hashMap = arr.reduce((a, c) => {
  a[c] = (a[c] || 0) + 1;
  return a;
}, {});


const pair = [];

// If the frequency is divided by 2 then push the key of the hashMap into pair array.
Object.entries(hashMap).forEach(([k, v]) => {
  if (v % 2 === 0) {
    [...Array(Math.floor(v / 2))].forEach(_ => pair.push(k));
  }
})

console.log(pair);

You can grab the frequency of each number, and then filter out any which have an odd frequency. You can then .flatMap() the frequencies to an array containing your number for each pair you found like so:

const a = [1,1,1,2,2,3,3,3,4,4,4,6,6,6,7,7];
const freq = a.reduce((m, n) => m.set(n, (m.get(n) || 0) + 1), new Map);
const res = [...freq].filter(([n, count]) => count % 2 == 0).flatMap(([n, c]) => Array(c/2).fill(n));
console.log(res);

This way, if you have four 1s (ie: two pairs of 1s), the filter will pick up on that, allowing you to flat-map the [1, 4] array to an array of [1, 1], which is merged into the larger resulting array.

You could create a helper map and keep the counts of each number as the values and the numbers itself as the keys. After iterating through the array, you only need to find the ones with a count divisible by 2:

var a = [1, 1, 1, 2, 2, 3, 3, 3, 4, 6, 6, 6, 7, 7]

function findDuplicates(arr) {

    const map = {};

    for (const curr of arr) {
        if (!map[curr]) {
            map[curr] = 0;
        }
        map[curr]++;
    }
    const res = [];
    for (const key in map) {
        if (map.hasOwnProperty(key) && map[key] % 2 === 0) {
            res.push(Number.parseInt(key));
        }
    }
    return res;
}

console.log(findDuplicates(a));

You can first count the occurrence of each numbers and if it is greater than 0 and divisible by 2 then add these to final result else don't

function getDuplicateArrayElements(arr) {
  let map = {}
  let results = [];

  for (let num of arr) {
    map[num] = map[num] || 0
    map[num]++
  }
  
  return Object.keys(map)
               .filter(v => map[v] && map[v] % 2 === 0)
               .map(v => new Array(map[v]/2).fill(+v))
               .flat()
               .sort()
}

var a = [1, 1, 1, 2, 2, 3, 3, 3, 4, 6, 6, 6, 7, 7,8,8,8,8];
var duplicateValues = getDuplicateArrayElements(a);
console.log(duplicateValues)

const a = {};
[1,1,1,2,2,3,3,3,4,6,6,6,7,7].forEach(v => {a[v] = a[v] ? a[v] + 1 : 1});
const l = [];
Object.keys(a).forEach(k => !(a[k] % 2) && l.push(k));

Another rather concise solution:

a = [1,1,1,2,2,3,3,3,4,4,4,6,6,6,7,7];
uniques = new Set(a); //filter out duplicates
res = [];
uniques.forEach((key)=>{
if(a.filter(elem => elem === key).length === 2){res.push(key)}; 
//filter out only the elements which match the key being tested
//if there are 2, push to result
})

Edit: even more concise, but perhaps less efficient:

a = [1,1,1,2,2,3,3,3,4,4,4,6,6,6,7,7];
res = Array.from(new Set(a.filter(elem => a.filter(el => el === elem).length === 2)));

Here you go:

 function getDuplicateArrayElements(arr){
    var dupilcates=arr.filter(x =>  arr.filter(y=>y==x).length==2);  
    var found=[];
    for(var i=0;i<dupilcates.length;i=i+2)
      found.push(dupilcates[i]);
    return found;
}

This will give you the desired pairs. with [1, 1, 1, 1, 2, 2, 3, 3, 3, 4, 6, 6, 6, 6, 7, 7] input it will return [1,1,2,6,6,7]:

function getDuplicateArrayElements(arr){
  let sorted_arr = arr.slice().sort();
  let results = [];
  let i = 0;
  while (i < sorted_arr.length) {
    let counter = 1;
    let j = i;
    while (sorted_arr[j] === sorted_arr[j+1]) {
      counter++;
      j++;
    }
    
    if (counter%2 == 0) {        
      results.push(...Array(counter/2).fill(sorted_arr[i]))
    }
    
    i += counter;
  }

  return results; 
} 

var a = [1, 1, 1, 1, 2, 2, 3, 3, 3, 4, 6, 6, 6, 6, 7, 7];
console.log(getDuplicateArrayElements(a));

Javascript has awesome JSON object, in my opinion, you can use json as a dictionary;

{ key: _value }.
Loop throw array one times, no sort, no slice

key is array's element value, _value is frequency

var frequencies = {};
for (let i = 0; i < a.length; a++) {
   if (result[a[i]] == 'over') continue;
   if (result[a[i]] == undefined) { // First times
       result[a[i]] = 1
   } else if (result[a[i]] == 1) { // Second times
       result[a[i]] = 2
   } else { // Ignore if > 2
       result[a[i]] = 'over'
   }
}
// result: {1: "over", 2: 2, 3: "over", 4: "over", 6: "over", 7: 2}

so now pick keys have value equal 2

function getDuplicateArrayElements(numbers: number[]): number[] {
  const occurences = new Map<number, number>();

  for (let number of numbers) {
    if (occurences.has(number)) {
      const current = occurences.get(number)!;
      occurences.set(number, current + 1);
    } else 
    occurences.set(number, 1)  
  }

  return (
    Array
      .from(occurences.entries())
      .reduce<number[]>(
        (accumulator, [key, value]) => {
          if (value === 2) {
            return accumulator.concat(key)
          }

          return accumulator
        },
        []
      )
  )
}
const a = [1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 6, 6, 6, 7, 7];

getDuplicateArrayElements(a); // [2, 7]
Related