比较基于 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;