Comparing two objects for matching values and pushing any non matching values to separate array, keep getting several duplicates

Viewed 142

I have two arrays of objects that I'm comparing using the value group(first array) and groupName(second array). I push all matching groups to one array called matching, and all non matching objects I push to another array called nonMatching.

The function to get matching seems to work fine, only adding the matching elements. The problem lies with the find non matching function. I've been testing with a mock data set for the first array and it only contains 7 items, yet when I check the nonMatching array after running my function I have 26 items total, most of which are duplicates.

I'm really not sure where I'm going wrong and why the matching logic works but the nonMatching doesn't.

arr1:

[
  {
    "group": "uncategorized"
  },
  {
    "group": "bla blah"
  },
  {
    "group": "options and cool sheet"
  },
  {
    "group": "baz"
  },
  {
    "group": "foo"
  },
  {
    "group": "bar"
  },
  {
    "group": "null"
  }
]

arr2:

[
  {
      "groupName": "maintenance and parts",
      "groupType": "video"
  },
  {
      "groupName": "loser product",
      "groupType": "list"
  },
  {
      "groupName": "options and cool sheet",
      "groupType": "list"
  },
  {
      "groupName": "uncategorized",
      "groupType": "list"
  }
]

Functions:

function isEqual(object1, object2) {
  return object1.group === object2.groupName; // returns boolean
}

const matchingGroups = []
const nonMatchingGroups = []

let findMatching = arr1.map(group => {
  arr2.map(config => {
    if(group.group === config.groupName){
      matchingGroups.push(group)
    }
  })
})

let findNonMatching = arr1.map(group => {
  arr2.map(config => {
    if(!isEqual(group, config)){
      nonMatchingGroups.push(group)
    } else {
      return null
    }
  })
})

console.log('matchingGroups', matchingGroups) // returns array[2]
console.log('nonMatchingGroups', nonMatchingGroups) // returns array[26]
1 Answers

It is because you're using the map and calculating if the group is equal to config for each and every element in the arr2.

You just need to find if the object exists in other or not. If the object doesn't exist then push the group to findNonMatching array. You can use find for this.

const arr1 = [
  {
    group: "uncategorized",
  },
  {
    group: "bla blah",
  },
  {
    group: "options and cool sheet",
  },
  {
    group: "baz",
  },
  {
    group: "foo",
  },
  {
    group: "bar",
  },
  {
    group: "null",
  },
];

const arr2 = [
  {
    groupName: "maintenance and parts",
    groupType: "video",
  },
  {
    groupName: "loser product",
    groupType: "list",
  },
  {
    groupName: "options and cool sheet",
    groupType: "list",
  },
  {
    groupName: "uncategorized",
    groupType: "list",
  },
];

function isEqual(object1, object2) {
  return object1.group === object2.groupName; // returns boolean
}

const matchingGroups = [];
const nonMatchingGroups = [];

let findMatching = arr1.map((group) => {
  arr2.map((config) => {
    if (group.group === config.groupName) {
      matchingGroups.push(group);
    }
  });
});

let findNonMatching = arr1.map((group) => {
  const objExist = arr2.find((config) => isEqual(group, config));
  if (!objExist) {
    nonMatchingGroups.push(group);
  }
});

console.log("matchingGroups", matchingGroups); // returns array[2]
console.log("nonMatchingGroups", nonMatchingGroups); // returns array[26]

FYI, You don't need to iterate twice to get this result. The same result can be easily achieved using reduce

const arr1 = [
  {
    group: "uncategorized",
  },
  {
    group: "bla blah",
  },
  {
    group: "options and cool sheet",
  },
  {
    group: "baz",
  },
  {
    group: "foo",
  },
  {
    group: "bar",
  },
  {
    group: "null",
  },
];

const arr2 = [
  {
    groupName: "maintenance and parts",
    groupType: "video",
  },
  {
    groupName: "loser product",
    groupType: "list",
  },
  {
    groupName: "options and cool sheet",
    groupType: "list",
  },
  {
    groupName: "uncategorized",
    groupType: "list",
  },
];

function isEqual(object1, object2) {
  return object1.group === object2.groupName; // returns boolean
}

const result = arr1.reduce(
  (acc, group) => {
    const objExist = arr2.find((config) => isEqual(group, config));
    if (objExist) acc[0].push(group);
    else acc[1].push(group);
    return acc;
  },
  [[], []]
);

const matchingGroups = result[0];
const nonMatchingGroups = result[1];

console.log(matchingGroups);
console.log(nonMatchingGroups);

Related