9

I'm still a junior at web dev and I am trying to solve this problem. I have to find the number of matching pairs in these arrays:

var ar1 = [10, 20, 20, 10, 10, 30, 50, 10, 20] // return 3 (2 pairs of 10 and 1 pair of 20)
var ar2 = [1, 1, 3, 1, 2, 1, 3, 3, 3, 3] // return 4 (2 pairs of 1 and 2 pairs of 3)

// I started to write my logic below but I'm stuck, could you please help me to solve this problem ?


// The last result I am returning is a filtered array with all the nbs that are superior to 1 and then can't figure out how to get the result of matching pairs :-(

function countPairs(n, ar) {
  const count = {};
  ar.forEach((nb) => (count[nb] = (count[nb] || 0) + 1));
  const values = Object.values(count);
  const filter = values.filter((value) => value > 1);
  return filter;
}

// 9 and 10 are the length of the arrays
console.log(countPairs(9, ar1))
console.log(countPairs(10, ar2))

Thank you very much for your help!

0

9 Answers 9

11

Perhaps there is a faster/better way to calculate this than this O(2n) solution, but it's something:

var ar1 = [10, 20, 20, 10, 10, 30, 50, 10, 20] // return 3 (2 pairs of 10 and 1 pair of 20)
var ar2 = [1, 1, 3, 1, 2, 1, 3, 3, 3, 3] // return 4 (2 pairs of 1 and 2 pairs of 3)

function countPairs(ar) {
  var obj = {};

  ar.forEach(item => {
    obj[item] = obj[item] ? obj[item] + 1 : 1;
  });
  
  return Object.values(obj).reduce((acc, curr) => {
    acc += Math.floor(curr / 2)
    return acc;
  }, 0);
}

console.log(countPairs(ar1))
console.log(countPairs(ar2))

This first calculates the number of occurences for each number and stores them in an Object. Once that is done, we reduce over the values and return the quotient from the division with 2 (to get the number of pairs in total).

Note: I removed the first argument from your function, because the array length is not needed as an argument. It can be obtained from the array you pass directly.

Sign up to request clarification or add additional context in comments.

Comments

8

We can achieve this in O(n) time. Maintain an object which keeps track whether a number have been found before, if it was found before, then it makes up a pair, so we increment the pairs count. If not we make the entry of that number in the object 1

function countPairs(arr) {
    let pairs = 0;
    const obj = {};
    arr.forEach(i => {
        if (obj[i]) {
            pairs += 1;
            obj[i] = 0;
        } else {
            obj[i] = 1;
        }
    });
    return pairs;
}

Comments

2

Simplest solution I can find:

create empty dictionary var t = {}; and use it to count each item in array arr.forEach (i => t[i] = (t[i] || 0) + 1);. After that take all keys Object.values(t) and sum .reduce((acc, p) => acc + ..., 0) each item counts divided by 2 p/2 with Int semantics of course Math.floor(...).

function countPairs(arr) {
  var t = {}; 
  arr.forEach (i => t[i] = (t[i] || 0) + 1);
  return Object.values(t).reduce((acc, p) => acc + Math.floor(p/2), 0);
}

console.dir(countPairs([1,2,2,2,2,3]));
console.dir(countPairs([1,2,2,2,2,2,3]));
console.dir(countPairs([1,2,2,2,2,2,2,3]));
console.dir(countPairs([10, 20, 20, 10, 10, 30, 50, 10, 20]));
console.dir(countPairs([1, 1, 3, 1, 2, 1, 3, 3, 3, 3]));

First argument in your implementation is not necessary. Please up-vote if answer was helpful

2 Comments

This is basically what I posted, with some minor semantical differences.
Yes... I've figured it out at the same time. I've spend some time trying to do it... your answer was published in mean time. I didn't see it before.
1

Concise approach with reduce method

const countPairs = arr => (pairs = [], arr.reduce((p, c) => (p[c] ? (pairs.push([p[c], c]), delete p[c]) : p[c] = c, p), {}), pairs.length)
console.log(countPairs([10, 20, 20, 10, 10, 30, 50, 10, 20]));

Comments

0

So, I wanted a more simpler solution to this problem since I'm just starting to learn to code and I'm teaching my self. I found this solution works perfectly for what you want. I didn't created this solution I found it on the internet(https://www.geeksforgeeks.org/count-equal-element-pairs-in-the-given-array/) I just translated it to JavaScript.

function countDuplicates(n, arr) {
  var count = 0;
  arr.sort();
  for (var i = 0; i < n;) {
    if (arr[i] === arr[i + 1]) {
      count++;
      i = i + 2;
    } else {
      i++;
    }
  }
  return count;
}
console.log(countDuplicates(9, [10, 20, 20, 10, 10, 30, 50, 10, 20]));

Comments

0

There are some more concise answers here, but here's the solution I have for you:

function countDuplicates(arr) {
  var counts = {}, sum = 0;
  for (var i = 0; i < arr.length; i++) {
    counts[arr[i].toString()] = (counts[arr[i].toString()] || 0) + 1;
  }
  for (var count in counts) {
    if (Object.prototype.hasOwnProperty.call(counts, count)) sum += Math.floor(counts[count] / 2);
  }
  return sum;
}

console.log(countDuplicates([10, 20, 20, 10, 10, 30, 50, 10, 20]));

Comments

0

I hope I have helped

function numberOfPairs(array) {
  let arr = [...array].sort();
  let result = 0;
  
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] == arr[i + 1]) {
      result++;
      arr.shift();
    }
  }

  console.log(result);
}

numberOfPairs(['blue', 'blue', 'blue', 1, 2, 5, 2, 1]);

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
0
let pairs =0; 
ar.sort(function(a, b){return a - b});
while(n>0){
let x=ar[1];
let y=ar.shift();
n-=1;
if (y === x) {
     pairs +=1;
    ar = ar.slice(1);
    n-=1;      
 } 
}

return pairs;

Comments

0

Pairs of the number 10 (each pair as [10, 10]) for every two occurrences of 10 in the input array. Triples of the number 20 (each triple as [20, 20, 20]) for every three occurrences of 20 in the input array.

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.