2

I have a function to remove non common elements between two arrays in javascript but the issue is my code reduces some items in the array and increases some. Below is my code

function canFormPairs(cleanSocks, dirtySocks) {
  let compared = [];
  cleanSocks.forEach(item => {
    dirtySocks.forEach(dItem => {
      if (item == dItem) {
        compared.push(item);
      }
    });
  });
  return compared;
}
console.log(canFormPairs([1, 5, 6, 7, 5, 6, 5, 56], [1, 5, 6, 7, 8, 5, 6, 7, 8, 78]));

The above code gives

[ 1, 5, 5, 6, 6, 7, 7, 5, 5, 6, 6, 5, 5 ]

Instead of the desired result of

[1, 1, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7]

When sorted

Please what is the issue with this code

5
  • 1
    You are right but thats not the problem here Commented Feb 21, 2019 at 9:30
  • I'm just trying to understand if there is anything that I do not understand, before I can jump to answer Commented Feb 21, 2019 at 9:30
  • Alrigth. Would edit Commented Feb 21, 2019 at 9:31
  • Would read on set now. Thanks. But what is the issue with this algorithm Commented Feb 21, 2019 at 9:33
  • Does position matter? Does it matter if left set has 2 fives and right set has 1 five? Commented Feb 22, 2019 at 8:33

5 Answers 5

7

Your current logic pushes the item for every unique index match between the two arrays. For example, with 7, 7 gets matched at index 3 (first array) and index 3 (second array), so it gets pushed once. Then, the next match is with index 3 (first array) and index 7 (second array). There are no more index matches other than 3-3 and 3-7, so only two 7 (values) get pushed.

I'd consider making a Set from both arrays, then combining both arrays and using .filter to remove elements not in both sets, and then sort the array:

function canFormPairs(a, b) {
  const setA = new Set(a);
  const setB = new Set(b);
  return [...a, ...b]
    .filter(item => setA.has(item) && setB.has(item))
    .sort((a, b) => a - b);
}
console.log(canFormPairs([1, 5, 6, 7, 5, 6, 5, 56], [1, 5, 6, 7, 8, 5, 6, 7, 8, 78]));

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

Comments

2

Try this

function canFormPairs(cleanSocks, dirtySocks) {
  let compared = [];
  let one = cleanSocks.filter(el => dirtySocks.includes(el));
  let two = dirtySocks.filter(el => cleanSocks.includes(el));
  compared = one.concat(two);
  compared.sort(function(a, b) {
    return a - b;
  });
  return compared;
}
console.log(canFormPairs([1, 5, 6, 7, 5, 6, 5, 56], [1, 5, 6, 7, 8, 5, 6, 7, 8, 78]));

Comments

0

Keeping this answer focused on why OP's code gives incorrect result.

Your algo reads like,

  • Having 2 arrays, a, b
  • Loop on a.
  • Loop on b.
  • If a[i] === b[i], push a[i] to result.

Issue:

  • You will have m*n items in result array. So for 1, since both have once only, you have it only 1 time. Similarly for 5, its 2*3 hence you get 6 times instead of 5. Output should be m+n instead.
  • Both the array can have duplicates and are not sorted. So final result will not be sorted.

Comments

0

I made some changes to your function and it works now:

function canFormPairs(cleanSocks, dirtySocks) {
    let compared = [];
    let cleanSocksUniqueItems = [];
    cleanSocks.map((item, index) => {
        cleanSocks.slice(index+1).map(elem => {
            if (item === elem && !cleanSocks.slice(0, index).includes(item)) {
               dirtySocks = [...dirtySocks, elem];
            }
        });
    });
    cleanSocksUniqueItems = Array.from(new Set(cleanSocks));
    cleanSocksUniqueItems.forEach(item => {
        dirtySocks.forEach(dItem => {
            if (item === dItem) {
                if (!compared.includes(item)) {
                    compared = [...compared, item];
                }
                compared = [...compared, item];
            }
        });
   });
   return compared.sort();
}
console.log(canFormPairs([1, 5, 6, 7, 5, 6, 5, 56], [1, 5, 6, 7, 8, 5, 6, 7, 8, 78]));

Comments

0

Here is a simple solution using flatMap, have a look.

Array.prototype.pairs = function(arr2){
var arr1= this;
let compared = [arr1, arr2].flatMap(function (x)
{
  return x.filter(a=> arr1.indexOf(a) != -1 && arr2.indexOf(a) != -1)
}).sort((a,b)=> a-b);

return compared
}

var res = [1, 5, 6, 7, 5, 6, 5, 56].pairs([1, 5, 6, 7, 8, 5, 6, 7, 8, 78])
console.log(res);

Comments

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.