Skip to content
Advertisement

Detecting mismatch where there are multiple occurences of array elements in more than one array

I have the following arrays:

const primary =
[
 {recordId:123, type: "Primary" },
 {recordId:123, type: "Primary" },
 {recordId:123, type: "Primary" },
 {recordId:9393, type: "Primary" },
 {recordId:9393, type: "Primary" },
 {recordId:9393, type: "Primary" },
];

const secondary = [
 {recordId:123, type: "Secondary" },
 {recordId:123, type: "Secondary" },
 {recordId:9393, type: "Secondary" },
 {recordId:9393, type: "Secondary" },
 {recordId:9393, type: "Secondary" },
];

So I want to display a list of recordIds where we don’t have an equal number of records in either array for given recordId.

e.g In above example recordId:123 has 3 x records in primary array but only 2 x in the secondary array, therefore because the number of records don’t match up for this Id I want to be able to report on this recordId.

I’ve had a go and this is what solution I’ve produced so far using vanilla Javascript:

const missingRecords = []

const primaryOccurences = primary.reduce((acc, val) 
 => acc.set(val.recordId, 1 +   (acc.get(val.recordId) || 0)), new Map());
const secondaryOccurences = secondary.reduce((acc, val) 
 => acc.set(val.recordId, 1 + (acc.get(val.recordId) || 0)), new Map());

console.log(primaryOccurences);
console.log(secondaryOccurences);

primaryOccurences.forEach((value,key)=> {
for (const[skey, svalue] of secondaryOccurences.entries()) {
 if(skey === key && value !== svalue) {
   missingRecords.push(key);
  }
 }
})

console.log(missingRecords);

const primary = [{
    recordId: 123,
    type: "Primary"
  },
  {
    recordId: 123,
    type: "Primary"
  },
  {
    recordId: 123,
    type: "Primary"
  },
  {
    recordId: 9393,
    type: "Primary"
  },
  {
    recordId: 9393,
    type: "Primary"
  },
  {
    recordId: 9393,
    type: "Primary"
  },
];

const secondary = [{
    recordId: 123,
    type: "Secondary"
  },
  {
    recordId: 123,
    type: "Secondary"
  },
  {
    recordId: 9393,
    type: "Secondary"
  },
  {
    recordId: 9393,
    type: "Secondary"
  },
  {
    recordId: 9393,
    type: "Secondary"
  },
];


const missingRecords = []

const primaryOccurences = primary.reduce((acc, val) => acc.set(val.recordId, 1 + (acc.get(val.recordId) || 0)), new Map());
const secondaryOccurences = secondary.reduce((acc, val) => acc.set(val.recordId, 1 + (acc.get(val.recordId) || 0)), new Map());

console.log(primaryOccurences);
console.log(secondaryOccurences);

primaryOccurences.forEach((value, key) => {
  for (const [skey, svalue] of secondaryOccurences.entries()) {
    if (skey === key && value !== svalue) {
      missingRecords.push(key);
    }
  }
})

console.log(missingRecords);

Running this code produces the following:

[123]

So is there a better alternative to the above from a performance standpoint? I’m open to other ideas / suggestions.

Advertisement

Answer

You can use only one map. Will be better for big arrays. It require only one loop. And you can detect if there are more records in the primary ( > 0) or in the secondary ( < 0)

Also you can rewrite reduce in for notation but it make sense only for large arrays

https://measurethat.net/Benchmarks/Show/19290/0/so-two-map-compare

const primary =
[
 {recordId:123, type: "Primary" },
 {recordId:123, type: "Primary" },
 {recordId:123, type: "Primary" },
 {recordId:9393, type: "Primary" },
 {recordId:9393, type: "Primary" },
 {recordId:9393, type: "Primary" },
];

const secondary = [
 {recordId:123, type: "Secondary" },
 {recordId:123, type: "Secondary" },
 {recordId:9393, type: "Secondary" },
 {recordId:9393, type: "Secondary" },
 {recordId:9393, type: "Secondary" },
];

const missingRecords = []

const occurences = primary.reduce((acc, val) => acc.set(val.recordId, 1 + (acc.get(val.recordId) || 0)), new Map());
secondary.reduce((acc, val) => acc.set(val.recordId, (acc.get(val.recordId) || 0) - 1), occurences);

for (const [skey, svalue] of occurences.entries()) {
    if (svalue !== 0) {
        missingRecords.push(skey);
    }
}

console.log(missingRecords);
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement