2

Compare 2 objects and return true only if two values are the same. If they are more than two same values or all or none return false. Example:

A = {a: 1, b: 2, c: 3};
B = {a: 1, b: 5, c: 7};
C = {a: 1, b: 2, c: 7};

A and B should return true because A.a and B.a are the same. A and C should return false because A.a and C.a and A.b and C.b are the same.

So far I have this function:

Link

But in the case, const ObB7 returns true and should be false.

And can this function be simplified?

function compareTwoObjects(ObA, ObB) {
  const { a, b, c } = ObA;
  const { a:d, b:e, c:f } = ObB;

  if (
    ((a === d && (a !== e && a !== f))
    || (a === e && (a !== d && a !== f))
    || (a === f && (a !== e && a !== d)))

    || ((b === d && (b !== e && b !== f))
    || (b === e && (b !== d && b !== f))
    || (b === f && (b !== e && b !== d)))

    || ((c === d && (c !== e && c !== f))
    || (c === e && (c !== d && c !== f))
    || (c === f && (c !== e && c !== d)))
  ) {
    return true;
  }
  return false;
}


const ObA = {a: 1, b: 2, c: 3};

const ObB0 = {a: 4, b: 5, c: 6}; // false
const ObB1 = {a: 4, b: 4, c: 4}; // false
const ObB2 = {a: 1, b: 1, c: 1}; // false
const ObB3 = {a: 2, b: 2, c: 2}; // false
const ObB4 = {a: 3, b: 3, c: 3}; // false
const ObB5 = {a: 1, b: 1, c: 7}; // false
const ObB6 = {a: 7, b: 2, c: 2}; // false
const ObB7 = {a: 7, b: 3, c: 3}; // false
const ObB8 = {a: 2, b: 3, c: 4};  // Should be false
const ObB9 = {a: 3, b: 7, c: 3}; // false

const ObB10 = {a: 5, b: 2, c: 3}; // true
const ObB11 = {a: 1, b: 5, c: 6}; // true
const ObB12 = {a: 0, b: 5, c: 3}; // true

console.log(compareTwoObjects(ObA, ObB0));
console.log(compareTwoObjects(ObA, ObB1));
console.log(compareTwoObjects(ObA, ObB2));
console.log(compareTwoObjects(ObA, ObB3));
console.log(compareTwoObjects(ObA, ObB4));
console.log(compareTwoObjects(ObA, ObB5));
console.log(compareTwoObjects(ObA, ObB6));
console.log(compareTwoObjects(ObA, ObB7));
console.log(compareTwoObjects(ObA, ObB8));
console.log(compareTwoObjects(ObA, ObB9));
console.log(compareTwoObjects(ObA, ObB10));
console.log(compareTwoObjects(ObA, ObB11));
console.log(compareTwoObjects(ObA, ObB12));
john_per
  • 320
  • 6
  • 16
  • 1
    You might want to look there: [Object comparison in JavaScript](https://stackoverflow.com/questions/1068834/object-comparison-in-javascript) – Pierre Mar 07 '19 at 16:30
  • [`Object.values()`](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Object/values) could simplify your current try. – Kévin Bibollet Mar 07 '19 at 16:32
  • Shouldn't ObB10 be false? I'm confused as to why you're using objects, when you're not comparing the keys. – Rice_Crisp Mar 07 '19 at 16:51
  • @Rice_Crisp you have right, ObB10 should be false – john_per Mar 08 '19 at 09:19

2 Answers2

2
function compareTwoObjects(a, b) {
  let matches = 0
  Object.keys(a).forEach(key => {
    if (b[key] && b[key] === a[key]) {
      matches++
    }
  })
  return matches === 1
}
Rice_Crisp
  • 1,242
  • 1
  • 16
  • 33
  • Try it on OPs data? Use the snippet editor – mplungjan Mar 07 '19 at 16:39
  • `return matches === 1` should be `return matches === 2`. Also, it would be nice if the post explained what the code did. :) – shuckster Mar 07 '19 at 17:30
  • 1
    No, there should only be one matching pair from what I can gather from the question. But the second example seems to counter what he said in the first example, so who knows. – Rice_Crisp Mar 07 '19 at 22:23
  • const A = {a: 1, b: 2, c: 3}; const B1 = {a: 1, b: 1, c: 1}; const B2 = {a: 1, b: 1, c: 7}; - B1 and B2 should also be false, the value can appear just once, and here value 1 appear more times – john_per Mar 08 '19 at 09:32
  • 1
    I modified just a bit your function and now works as I expect, but it is still your logic and I accept the answer. https://jsfiddle.net/perija/tgr8zkb1/1/ – john_per Mar 08 '19 at 09:54
0

You can use reduce

Here idea is

  • Get keys of one object.
  • Match values of both object for each key if they are equal increment op by 1 and if not just return op without any change.
  • In the end just check if the op === 2 return true else return false

let A = {a: 1, b: 2, c: 3};
let B = {a: 1, b: 5, c: 7};
let C = {a: 1, b: 2, c: 7};

let compare = (a,b)=>{
  let op = Object.keys(a).reduce((op,inp)=>{
      if(a[inp] === b[inp]){
        op++
      } return op;
  },0)
  return op === 2 ? true : false
}

console.log(compare(A,B))
console.log(compare(A,C))
console.log(compare(C,A))
Code Maniac
  • 37,143
  • 5
  • 39
  • 60
  • Why reduce, why not forEach or some? – mplungjan Mar 07 '19 at 16:33
  • @mplungjan yes forEach can be used. but i am not sure how will you use `some` in this case – Code Maniac Mar 07 '19 at 16:35
  • Perhaps not some then – mplungjan Mar 07 '19 at 16:36
  • const A = {a: 1, b: 2, c: 3}; const B1 = {a: 5, b: 2, c: 3}; const B2 = {a: 1, b: 5, c: 6}; const B3 = {a: 0, b: 5, c: 3}; console.log(compare(A,B1)) - returns true, and should be false; console.log(compare(A,B2)) - returns false, and should be true; console.log(compare(A,B3)) - returns false, and should be true; – john_per Mar 08 '19 at 09:14