Reputation: 4148
I am trying to compare 2 lists based on 2 different columns and get the difference.
const list1 = [[121,"7/2/2019"], [131,"7/22/2019"], [141, ]]
const list2 = [[121, ], [131, ], [141, ]]
In the above 2 lists, I am trying to compare list1 with list2 based on the 2 columns - col1 and col2. First columnn (col1) [121,131,141] will always be the same in both the lists.
For every unique column 1 (col1) [121,131,141] in list1, compare the corresponding element in list2 based on second column, and if it is different, I am trying to output it to a different list
Result = [[121,"7/2/2019"], [131,"7/22/2019"]
Another example is
const list1 = [[121,"7/2/2019"], [131,"7/22/2019"], [141, ]]
const list2 = []
Result = [[121,"7/2/2019"], [131,"7/22/2019"], [141, ]]
I tried with the below code but it does not yield my desired result
const obj1 = list1.reduce((o, e) => Object.assign(o, {[e]: true}), {});
const obj2 = list2.reduce((o, e) => Object.assign(o, {[e]: true}), {});
const list3 = list2.filter(e => !obj1[e]);
const list4 = list2.concat(list1.filter(e => !obj2[e]));
Any leads/suggestions would be appreciated.
Upvotes: 0
Views: 105
Reputation: 201388
As other pattern, for example, how about using Map
as follows?
const sample = (list1, list2) => {
const m = new Map(list2);
return list1.filter(([a, b]) => !m.has(a) || m.get(a) != b);
}
// Sample pattern 1.
const list1 = [[121, "7/2/2019"], [131, "7/22/2019"], [141,]];
const list2 = [[121,], [131,], [141,]];
const res1 = sample(list1, list2);
// Sample pattern 2.
const list3 = [];
const res2 = sample(list1, list3);
console.log(res1)
console.log(res2)
In above sample script, 2nd element of [141,]
is undefined
. By this, the output value of this becomes [141]
. If you want to output this value as the length of 2, how about modifying above script as follows?
From
return list1.filter(([a, b]) => !m.has(a) || m.get(a) != b);
To
return [...new Map(list1)].filter(([a, b]) => !m.has(a) || m.get(a) != b);
You can test this with the following script.
const sample = (list1, list2) => {
const m = new Map(list2);
return [...new Map(list1)].filter(([a, b]) => !m.has(a) || m.get(a) != b);
}
// Sample pattern 1.
const list1 = [[121, "7/2/2019"], [131, "7/22/2019"], [141,]];
const list2 = [[121,], [131,], [141,]];
const res1 = sample(list1, list2);
// Sample pattern 2.
const list3 = [];
const res2 = sample(list1, list3);
console.log(res1)
console.log(res2)
From your following replying,
If i read the dates from the google sheets, my lists are list1 = [[FH121, Fri Jul 12 00:00:00 GMT-04:00 2019], [FH131, Fri Jul 12 00:00:00 GMT-04:00 2019], [FH141, ]] and list2 = [[FH121, Fri Jul 12 00:00:00 GMT-04:00 2019], [FH131, Fri Jul 12 00:00:00 GMT-04:00 2019], [FH141, Wed Jul 10 00:00:00 GMT-04:00 2019]]. Sample function does not work as it returns all elements in list1 rather than just outputting one element which is [FH141, Wed Jul 10 00:00:00 GMT-04:00 2019]
I couldn't notice that the value of 2nd element in your samples was the date object. This is due to my poor skill. From your replying, I modified above script as follows.
const list1 = [["FH121", new Date("2019-07-12 00:00:00")], ["FH131", new Date("2019-07-12 00:00:00")], ["FH141", ]];
const list2 = [["FH121", new Date("2019-07-12 00:00:00")], ["FH131", new Date("2019-07-12 00:00:00")], ["FH141", new Date("2019-07-10 00:00:00")]];
const m = new Map(list1);
const r = list2.filter(([a, b]) => !m.has(a) || (m.get(a) && m.get(a).getTime()) != (b && b.getTime()));
console.log(r);
Upvotes: 1
Reputation: 14527
If col(1) contains only unique values you can convert the data into an object where col(1) has keys and col(2) has values:
const list1 = [[121,"7/2/2019"], [131,"7/22/2019"], [141, ]];
const list2 = [[121, ], [131, ], [141, ]];
const obj1 = Object.fromEntries(list1);
const obj2 = Object.fromEntries(list2);
var res = [];
for (prop in obj1) {
if (obj2.hasOwnProperty(prop) && obj2[prop] != obj1[prop]) {
res.push([prop, obj1[prop]]);
}
}
console.log(res)
Your another example needs nothing but one line:
if (list2.length == 0) var res = list1;
Upvotes: 1
Reputation: 18784
Try this to compare rows in list1
to the rows in list2
that appear at the same position in their respective arrays:
const difference = list1.filter((row, index) => row[1] !== list2[index][1]);
If the rows are not guaranteed to appear in the same position, try this:
const list1 = [[121, "7/2/2019"], [131, "7/22/2019"], [141,]];
const list2 = [[121,], [131,], [141,]];
const difference = list1.filter((row1, index) => {
const list2row = list2.filter(row2 => row2[0] === row1[0])[0];
return !Array.isArray(list2row) || row1[1] !== list2row[1];
});
Upvotes: 2