根据属性组合对象数组和内部数组

时间:2020-06-14 20:40:07

标签: javascript arrays object

说我有一个看起来像这样的数据结构:

data = [
        {title: "Alpha", content: [{ // 1 item }]},
        {title: "Beta", content: [{ // 10 items }]},
        {title: "Beta", content: [{ // 12 items }]}, 
        {title: "Beta", content: [{ // 8 items }]} 
       ]

我想找出一个归约函数,该函数将返回以下结构:

data = [
        {title: "Alpha", content: [{ // 1 item }]},
        {title: "Beta", content: [{ // 30 items }]}
       ]

我尝试查看一些根据标题使用reduce的答案,但是它没有返回带有累积内容数组的新结构,例如:

data = data.reduce((x, e) => {
          x.push(
            Object.assign(
              {},
              e,
              messages.find((x) => x.title == e.title)
            )
          )
          return x
        }, [])

任何帮助都会很棒。

3 个答案:

答案 0 :(得分:2)

这可能有帮助-

var data = [{
    title: "Alpha",
    content: [1, 2, 3, 4, 5]
  },
  {
    title: "Beta",
    content: [6, 7, 8, 9, 10]
  },
  {
    title: "Beta",
    content: [11, 12, 13, 14, 15]
  },
  {
    title: "Beta",
    content: [16, 17, 18, 19, 20]
  }
]

data = data.reduce((array, item) => {
  const existingItem = array.find(innerItem => innerItem.title === item.title);
  if (!!existingItem) {
    existingItem.content = [...existingItem.content, ...item.content];
  } else {
    array.push(item);
  }
  return array;
}, []);


console.log(data);

答案 1 :(得分:2)

您不需要使用.finddata = [ {title: "Alpha", content: [{ 1:1 }]}, {title: "Beta", content: [{2:2 }]}, {title: "Beta", content: [{ 3:3}]}, {title: "Beta", content: [{4:4}] } ] console.log( Object.values(data.reduce((acc,{title,content})=>{ acc[title] ? acc[title].content.push(...content) : acc[title] = { title, content } return acc },{}) ))每次迭代都必须搜索整个数组。

使用reduce和对象映射来收集重复对象,Object.values使用对象来解包数组。 spread syntax作为推送参数。

data = [
        {title: "Alpha", content: [{ 1:1 }]},
        {title: "Beta", content: [{2:2 }]},
        {title: "Beta", content: [{ 3:3}]}, 
        {title: "Beta", content: [{4:4}] }
       ]
function values(obj){
  return Object.keys(obj).map(k=>obj[k])
}
console.log(
values(data.reduce((acc,x)=>{
  acc[x.title] = acc[x.title] || {title: x.title, content: []}
  acc[x.title].content = acc[x.title].content.concat(x.content)
  return acc
},{})
))

如果需要与IE兼容,则上述链接的文档上有一个polyfill。这也将起作用:

AtomicInteger

答案 2 :(得分:0)

我对@ user120242代码进行了小的更改。

data = [
        {title: "Alpha", content: [{ 1:1 }]},
        {title: "Beta", content: [{2:2 }]},
        {title: "Beta", content: [{ 3:3}]}, 
        {title: "Beta", content: [{4:4}] }
       ]
let acc={};
data.forEach((x)=>{
  acc[x.title] = acc[x.title] || {title: x.title, content: []}
  acc[x.title].content = acc[x.title].content.concat(x.content)
}
)
console.log(acc)