【问题标题】:How to compare two arrays with objects to filter the ones that are similar (vanilla JS)如何将两个数组与对象进行比较以过滤相似的数组(vanilla JS)
【发布时间】:2019-12-05 08:39:32
【问题描述】:

问题

给定以下两个数组:

const myArr1 = [
 { locationPath: 'R0', locationOnGrid: { x: '0', y: '0' } }, // same as second in myArr2
 { locationPath: 'U5', locationOnGrid: { x: '1', y: '0' } },
 { locationPath: 'L3', locationOnGrid: { x: '3', y: '7' } } // same as second in myArr2
]

const myArr2 = [
 { locationPath: 'D0', locationOnGrid: { x: '0', y: '0' } }, // same as second in myArr1
 { locationPath: 'L5', locationOnGrid: { x: '3', y: '7' } }, // same as third in myArr1
 { locationPath: 'L7', locationOnGrid: { x: '0', y: '1' } },
 { locationPath: 'R2', locationOnGrid: { x: '2', y: '2' } }
]

// Do something to 'filter' out the objects that are similar.

结果

那么我想做的比较后也能做的,就是过滤掉某个结果:

// Result of the 'filter' function
const found = [
  { locationPath: 'R0', locationOnGrid: { x: '0', y: '0' } },
  { locationPath: 'L5', locationOnGrid: { x: '3', y: '7' } }
];

// and want to do something like the following on the found array:
const startingPoint = ({locationOnGrid}) => {
    return JSON.stringify(locationOnGrid) !== JSON.stringify({ x: '0', y: '0' });
};
const filteredFound = found.filter(startingPoint);
console.log(filteredFound);

// output:
// Array(1)
// 0: {locationPath: "L5", locationOnGrid: {…}}

到目前为止我尝试过的:

有一些 Stackoverflow 问题与两个数组之间的比较有关。例如问题Simplest code for array intersectionHow to filter array by comparing two elements 非常接近。

// does not work
const found = myArr2.filter((item, index) => {
  return
  (
    item.locationOnGrid.x === myArr1[index].locationOnGrid.x &&
    item.locationOnGrid.y === myArr1[index].locationOnGrid.y
  );
});
console.log(found);

另外两个数组也不一定有相同数量的对象。在示例中 myArr2 还有 1 个对象。所以这行得通。但对于另一种情况,很可能是 myArr1 比 myArr2 拥有更多的对象。

【问题讨论】:

  • 为什么是'L5' 而不是'L3'
  • 那些是生成的。所以这些不必相等。
  • @Remi 在输出中,第一个对象取自数组 1,第二个对象取自第二个数组,为什么不取自第一个数组。这就是尼娜的要求
  • @Remi 为什么found 数组包含[R0, L5] 而不是[R0, L3][D0, L5]
  • @Remi R0D0 坐标相同,L3L5 坐标相同。为什么结果是 [R0, L5] 而不是 [R0, L3][D0, L5]

标签: javascript arrays


【解决方案1】:

您可以获得具有标准化键/值对的Set,按键排序并创建JSON

然后过滤第一个数组,得到常见的locationOnGrid对象。

const
    stringified = o => JSON.stringify(Object.entries(o).sort((a, b) => a[0].localeCompare(b[0]))),
    array1 = [{ locationPath: 'R0', locationOnGrid: { x: '0', y: '0' } }, { locationPath: 'U5', locationOnGrid: { x: '1', y: '0' } }, { locationPath: 'L3', locationOnGrid: { x: '3', y: '7' } }],
    array2 = [{ locationPath: 'D0', locationOnGrid: { x: '0', y: '0' } }, { locationPath: 'L5', locationOnGrid: { x: '3', y: '7' } }, { locationPath: 'L7', locationOnGrid: { x: '0', y: '1' } }, { locationPath: 'R2', locationOnGrid: { x: '2', y: '2' } }],
    set2 = new Set(array2.map(({ locationOnGrid }) => stringified(locationOnGrid))),
    common = array1.filter(({ locationOnGrid }) => set2.has(stringified(locationOnGrid)));

console.log(common);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 太棒了。关于您之前的问题,为什么是“L5”而不是“L3”。在此答案中,您将获得 L3。如果您要切换两个数组(array1.map(...array2.filter),您将得到“L3”而不是“L5”。太好了!
猜你喜欢
  • 1970-01-01
  • 2020-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-04
  • 1970-01-01
相关资源
最近更新 更多