【问题标题】:Find intersections in array of arrays of objects在对象数组的数组中查找交点
【发布时间】:2019-07-25 02:20:15
【问题描述】:

假设我有以下包含对象数组(歌曲)的数组:

[
  [
    {
      name: 'I Want You Back',
      id: 1
    },
    {
      name: 'ABC',
      id: 2
    }
  ],
  [
    {
      name: 'I Want You Back',
      id: 1
    },
    {
      name: 'Dont Stop Me Now',
      id: 3
    }
  ],
  [
    {
      name: 'I Want You Back',
      id: 1
    },
    {
      name: 'ABC',
      id: 2
    }
  ],
]

我希望遍历我的数据并返回在 every 数组中找到的对象,所以在这种情况下,返回值将是:

{
   name: 'I Want You Back',
   id: 1
}

到目前为止,我只对字符串数组进行了处理,而不是对象,如下所示:

const arrays = [
  ['I Want You Back', 'ABC'],
  ['I Want You Back', 'Dont stop me now'],
  ['I Want You Back', 'ABC']
];

const result = arrays.shift().filter((v) => {
  return arrays.every((a) => {
    return a.indexOf(v) !== -1;
  });
});

// result = ["I Want You Back"]

我一直在尝试,但我无法将相同的逻辑应用于我的对象(以及它们的名称或 ID)。如果你们中的一些人告诉我你会怎么做,我真的很感激。

【问题讨论】:

标签: javascript


【解决方案1】:

您可以通过唯一的id 来计算对象,然后通过查找计数与数组长度相同的对象:

const songs = [[{name: 'I Want You Back',id: 1},{name: 'ABC',id: 2}],[{name: 'I Want You Back',id: 1},{name: 'Dont Stop Me Now',id: 3}],[{name: 'I Want You Back',id: 1},{name: 'ABC',id: 2}],]

// count of each unique id
let counts  = songs.reduce((count, arr) => {
  arr.forEach(obj => {
    if (!count[obj.id]) count[obj.id] = {obj, count: 0}
    count[obj.id].count += 1  
  })
  return count
}, {})

// now filter out all whose count isn't the length
// and map to retreive just the object
let intersect = Object.values(counts)
                .filter(o => o.count == songs.length)
                .map(o => o.obj)

console.log(intersect)

当然,如果对象相等性是通过值来测试的,这会容易得多,但因为它不是你需要跳过一些额外的箍。

【讨论】:

  • 这似乎是一个很好的解决方案!我会测试一下,过一会儿再回复你。 “如果对象相等性是通过值测试的”,这意味着每个数组都有相同对象的实例?
  • 只需确保每个数组不包含重复项,否则如果您有一个包含重复项的数组,则无法通过上述计数排序正确处理。然而,这将是不寻常的情况,但我会让你知道。
  • 注意@MichaelKnight,每首歌对于每个阵列都是独一无二的,所以我不应该遇到这个问题。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-16
  • 2011-01-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多