JavaScript对象数组包含相同的数组数据。

7
我会尽力帮助您进行翻译。以下是需要翻译的内容:

我尝试将所有相同的数据值放入一个对象数组中。这是我的输入:

var a = [{
    name: "Foo",
    id: "123",
    data: ["65d4ze", "65h8914d"]
  },
  {
    name: "Bar",
    id: "321",
    data: ["65d4ze", "894ver81"]
  }
]

我需要一个类似于以下的结果:
["65d4ze"]

我想循环遍历我的对象以获得此输出,但我完全迷失了...... 我不知道如何知道结果是否在所有数据数组中。

var a = [{
        name: "Foo",
        id: "123",
        data: ["65d4ze", "65h8914d"]
      },
      {
        name: "Bar",
        id: "321",
        data: ["65d4ze", "894ver81"]
      }
    ],
  b = [],
  c = []
a.forEach(function(object) {
  b.push(object.data.map(function(val) {
    return val;
    })
  );
});

console.log(b);


3
可能是JavaScript中数组交集的最简代码的重复问题。 - James Long
@JamesLong 我不理解重复的部分,为什么这个答案能帮到我? - Kamoulox
@Eddie 我需要将所有数组放入键数据中。这个键存在于我的主数组的所有对象中。 - Kamoulox
@Kamoulox,你有两个数组(a[0].data和a[1].data)。你似乎想要一个包含两个数组中所有出现的值的数组。除非我误读了你的问题。 - James Long
@Kamoulox不是很理解这句话:“我不知道该如何确定结果是否在所有数据阵列中。” 如果你能澄清一下,我可以帮你。 - Himanshu Shekhar
显示剩余3条评论
5个回答

12
你可以使用Array#map, Array#reduce, Array#filter, SetSet#has方法来映射data并获取共同的值。

var array = [{ name: "Foo", id: "123", data: ["65d4ze", "65h8914d"] }, { name: "Bar", id: "321", data: ["65d4ze", "894ver81"] }],
    key = 'data',
    common = array
        .map(o => o[key])
        .reduce((a, b) => b.filter(Set.prototype.has, new Set(a)));

console.log(common);


我有些困难理解这段代码 b.filter(Set.prototype.has, new Set(a))。但它完美地运行了,谢谢。 - Kamoulox
5
filter有两个参数,一个是回调函数的原型函数 Set.has,它检查一个值是否在一个set中。在这一点上,该方法无法工作,因为它需要一个Set实例。第二个参数是thisArg,您可以交出一个对象,在回调函数中将其用作this。也许另一种使用会更清晰。您可以使用绑定了此的回调函数进行相同的操作:Set.prototype.has.bind(new Set(a)),现在它已经成为一个带有this的函数。 - Nina Scholz
使用数组 common = array .map(o => o[key]) .reduce((a, b) => b.filter(Array.prototype.includes, a)); - Pranav C Balan
@PranavCBalan,Array#includes使用第二个参数fromIndex,并使用回调的索引值获取该值... - Nina Scholz
@NinaScholz:哎呀,没错,那会引起问题 :) - Pranav C Balan

3
你可以使用 Array#filter 方法。通过检查一个值是否存在于所有其他对象属性(数组)中,使用Array#every方法来检查这个值是否存在于所有剩余的数组中,来过滤第一个数组。
let res = a[0].data.filter(v => a.slice(1).every(a => a.data.includes(v)));

var a = [{
    name: "Foo",
    id: "123",
    data: ["65d4ze", "65h8914d"]
  },
  {
    name: "Bar",
    id: "321",
    data: ["65d4ze", "894ver81"]
  }
];

let res = a[0].data.filter(v => a.slice(1).every(a => a.data.includes(v)));

console.log(res)


1

var a = [{
      name: "Foo",
      id: "123",
      data: ["65d4ze", "65h8914d"]
    },
    {
      name: "Bar",
      id: "321",
      data: ["65d4ze", "894ver81"]
    }
  ],
  b = {};
a.forEach(function(i) {
  i.data.forEach(function(j) {
    if (!b.hasOwnProperty(j)) {
      b[j] = 0;
    }
    b[j] = b[j] + 1;
  });
});
c = []
for (var i in b) {
  if (b.hasOwnProperty(i)) {
    if (b[i] > 1) {
      c.push(i)
    }
  }
}
console.log(c);


1
使用数组中的flat函数:

var a = [{
        name: "Foo",
        id: "123",
        data: ["65d4ze", "65h8914d"]
      },
      {
        name: "Bar",
        id: "321",
        data: ["65d4ze", "894ver81"]
      }
    ],
  b = [],
  c = []
a.forEach(function(object) {
  b.push(object.data.map(function(val) {
    return val;
    })
  );
});

console.log(b.flat());


谢谢你的回答,那是一段很棒的代码。但是在我的浏览器上 flat 不起作用。 - Kamoulox

1
你可以在每个数据数组上使用 reduceconcat,并检查每个项的计数。
最后,检查数组中所有对象是否都包含该项,如果是,则返回该项。
请注意,此函数仅适用于提取在数组中所有对象中具有相同出现次数的项。

If an item has duplicates, but does not fulfill the above condition, it would not be extracted.

let a = [{name: "Foo",id: "123",data: ["65d4ze", "65h8914d"]},{name: "Bar",id: "321",data: ["65d4ze", "894ver81"]}]

let arr = a.reduce((prev,next) => prev.data.concat(next.data))
let counts = {};
let result = [];
for (var i = 0; i < arr.length; i++) {
  var num = arr[i];
  counts[num] = counts[num] ? counts[num] + 1 : 1;
}

for (let i in counts) {
    if (counts[i] === a.length) {
        result.push(i)
    }
}
console.log(result)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接