查找共享相同数组值的对象

Find objects that share the same array value

我有以下对象数组:

[
    {
        "id": "5ffcab3a065d103265f92bfc",
        "label": "Test Group 1",
        "channels": [
            "44332"
        ]
    },
    {
        "id": "5f85362e573c400e91bb7b15",
        "label": "Test Group 2",
        "channels": [
            "85705",
            "87984"
        ]
    }
]

我正在尝试通过 channels 值关联对象。如果两个对象在它们的 channels 数组中共享相同的值,我希望输出它们的 ID。

首先我们注意到这种关系(共享一个公共频道)是不可传递的:

如果 A 与 B 相关,B 与 C 相关,则不表示 A 与 C 相关。

但是该关系是可交换的:

如果 A 与 B 相关,则 B 与 A 相关。

因此,一个可能有用的输出可能是一个 排序对 id 的列表。我们不能指望将它们分组到更大的组中,因为缺少传递性会带来问题。

为了提取这些对,您可以首先按频道对 ID 进行分组,即对于每个频道,您将有一个 ID 列表。

然后解决方案由您可以从 same 列表中取出的每个可能的排序对组成。我说排序,因为由于关系的交换性质,反向对不提供额外信息,所以这些可以排除。

应从结果中删除重复的对。

为此我们可以使用映射和集合:

// Some example data
let data = [
    { id: "a", channels: [1, 2, 3] },
    { id: "b", channels: [2, 4, 6] },
    { id: "c", channels: [3, 6, 9] },
    { id: "d", channels: [4, 8, 12] },
    { id: "e", channels: [5, 10, 15] },
]

// Get the object ids grouped per channel
let temp = data.flatMap(({id, channels}) => channels.map(channel => [channel, id]));
let map = new Map(temp.map(([channel]) => [channel, []]));
for (let [channel, id] of temp) map.get(channel).push(id);
// Create unique pairs of connected ids
let set = new Set(Array.from(map.values(), ids =>
    ids.map(id =>
         ids.map(id2 => id < id2 && JSON.stringify([id, id2]))
    )
).flat(2).filter(Boolean));
// Extract result
let result = Array.from(set, JSON.parse);

console.log(result);