比较基于 2 列的 2 个不同列表
Compare 2 different lists based on 2 columns
我正在尝试比较基于 2 个不同列的 2 个列表并找出差异。
const list1 = [[121,"7/2/2019"], [131,"7/22/2019"], [141, ]]
const list2 = [[121, ], [131, ], [141, ]]
在上面的 2 个列表中,我试图根据 2 列 - col1 和 col2 来比较 list1 和 list2。第一列 (col1) [121,131,141] 在两个列表中始终相同。
对于list1中的每个唯一列1(col1)[121,131,141],根据第二列比较list2中的相应元素,如果不同,我试图将它输出到不同的列表
Result = [[121,"7/2/2019"], [131,"7/22/2019"]
另一个例子是
const list1 = [[121,"7/2/2019"], [131,"7/22/2019"], [141, ]]
const list2 = []
Result = [[121,"7/2/2019"], [131,"7/22/2019"], [141, ]]
我尝试了以下代码,但没有产生我想要的结果
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]));
任何 leads/suggestions 将不胜感激。
尝试将 list1
中的行与 list2
中出现在各自数组中相同位置的行进行比较:
const difference = list1.filter((row, index) => row[1] !== list2[index][1]);
如果不能保证行出现在同一位置,试试这个:
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];
});
作为其他模式,例如,使用Map
怎么样?
示例脚本:
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)
注:
在上面的示例脚本中,[141,]
的第二个元素是 undefined
。这样,它的输出值就变成了[141]
。如果想把这个值输出为2的长度,那么修改上面的脚本如何?
来自
return list1.filter(([a, b]) => !m.has(a) || m.get(a) != b);
到
return [...new Map(list1)].filter(([a, b]) => !m.has(a) || m.get(a) != b);
您可以使用以下脚本对此进行测试。
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)
参考文献:
已添加:
根据您的以下回复,
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]
我没注意到你样本中第二个元素的值是日期对象。这是我手艺不好的缘故。根据您的回复,我修改了上面的脚本如下。
修改后的脚本:
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);
如果 col(1) 仅包含唯一值,您可以将数据转换为一个对象,其中 col(1) 具有键而 col(2) 具有值:
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)
你的另一个例子只需要一行:
if (list2.length == 0) var res = list1;
我正在尝试比较基于 2 个不同列的 2 个列表并找出差异。
const list1 = [[121,"7/2/2019"], [131,"7/22/2019"], [141, ]]
const list2 = [[121, ], [131, ], [141, ]]
在上面的 2 个列表中,我试图根据 2 列 - col1 和 col2 来比较 list1 和 list2。第一列 (col1) [121,131,141] 在两个列表中始终相同。
对于list1中的每个唯一列1(col1)[121,131,141],根据第二列比较list2中的相应元素,如果不同,我试图将它输出到不同的列表
Result = [[121,"7/2/2019"], [131,"7/22/2019"]
另一个例子是
const list1 = [[121,"7/2/2019"], [131,"7/22/2019"], [141, ]]
const list2 = []
Result = [[121,"7/2/2019"], [131,"7/22/2019"], [141, ]]
我尝试了以下代码,但没有产生我想要的结果
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]));
任何 leads/suggestions 将不胜感激。
尝试将 list1
中的行与 list2
中出现在各自数组中相同位置的行进行比较:
const difference = list1.filter((row, index) => row[1] !== list2[index][1]);
如果不能保证行出现在同一位置,试试这个:
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];
});
作为其他模式,例如,使用Map
怎么样?
示例脚本:
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)
注:
在上面的示例脚本中,
[141,]
的第二个元素是undefined
。这样,它的输出值就变成了[141]
。如果想把这个值输出为2的长度,那么修改上面的脚本如何?来自
return list1.filter(([a, b]) => !m.has(a) || m.get(a) != b);
到
return [...new Map(list1)].filter(([a, b]) => !m.has(a) || m.get(a) != b);
您可以使用以下脚本对此进行测试。
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)
参考文献:
已添加:
根据您的以下回复,
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]
我没注意到你样本中第二个元素的值是日期对象。这是我手艺不好的缘故。根据您的回复,我修改了上面的脚本如下。
修改后的脚本:
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);
如果 col(1) 仅包含唯一值,您可以将数据转换为一个对象,其中 col(1) 具有键而 col(2) 具有值:
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)
你的另一个例子只需要一行:
if (list2.length == 0) var res = list1;