从包含对象的嵌套数组的数组中创建新对象

4

我有一个包含嵌套数组的数组:

const options = [
  [
    {
      label: "Blue",
      option_id: "1"
    },
    {

      label: "Small",
      option_id: "2"
    }
  ],
  [
    {
      label: "Red",
      option_id: "1"
    },
    {
      label: "Large",
      option_id: "2"
    }
  ]
];


我想从每对元素中创建一个对象数组,例如:
[
 {
   label: ”Blue Small“,
   option_id: [1,2]
 },
...
]

编辑:感谢大家提供的出色答案。

6个回答

5
使用.map遍历options数组,并将每个子数组使用reduce方法转化为一个对象:

const options = [
  [
    {
      label: "Blue",
      option_id: "1"
    },
    {

      label: "Small",
      option_id: "2"
    }
  ],
  [
    {
      label: "Red",
      option_id: "1"
    },
    {
      label: "Large",
      option_id: "2"
    }
  ]
];
const result = options.map(arr =>
  arr.reduce(
    (a, { label, option_id }) => {
      a.label += (a.label ? ' ' : '') + label;
      a.option_id.push(option_id);
      return a;
    },
    { label: '', option_id: [] }
  )
);
console.log(result);


3

reduce是实现这些数组操作的好方法。

const options = [
  [
    {
      label: "Blue",
      option_id: "1"
    },
    {

      label: "Small",
      option_id: "2"
    }
  ],
  [
    {
      label: "Red",
      option_id: "1"
    },
    {
      label: "Large",
      option_id: "2"
    }
  ]
];

const newArray = options.reduce((prev,current)=>{
  const label = current.map(o=>o.label).join(' ')
  const optionid = current.map(o=>o.option_id)
  return [...prev,{option_id:optionid,label}]
},[])

console.log(newArray)

这里的 return [...prev, {}] 可能过于花哨了。它构建了一个全新的列表,而在这种情况下修改累加器 - 在现有列表中进行 push 操作是完全有效的。 - tevemadar
没错,在这里使用 push 是完全有效的,但我更喜欢不修改累加器而返回一个新值。 - Prithwee Das
我同意@tevemadar的观点。return [...prev, {}]看起来很高级,但如果列表很大,那么这就是一个纯粹的性能问题。 - Ritwick Dey
如何进行反向操作? - Akash Dubey

2
你可以映射并收集数据。原始答案翻译成"最初的回答"。

const
    options = [[{ label: "Blue", option_id: "1" }, { label: "Small", option_id: "2" }], [{ label: "Red", option_id: "1" }, { label: "Large", option_id: "2" }]],
    result = options.map(a => a.reduce((r, { label, option_id }) => {
        r.label += (r.label && ' ') + label;
        r.option_id.push(option_id);
        return r;
    }, { label: '', option_id: [] }));

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


嗨,需要一点帮助。(r.label && ' ') 是什么意思? - brk
2
它会切换所需的空格。在开始时,r.label 是一个空字符串并且是假值。这被取出并添加了 label,没有空格。如果 r.label 不是一个空字符串,它就会取出空格并添加 label。基本上,这是 CertainPerfomance(a.label ? ' ' : '') 部分的非常简短的形式。 - Nina Scholz
1
r.label ? ' ' : '' 相同。 - Stathis Ntonas
1
谢谢。感激不尽。 - brk

1
使用mapreducemap将返回一个新的数组,在map的回调函数内部,使用reduce,并默认将一个对象传递给累加器。

const options = [
  [{
      label: "Blue",
      option_id: "1"
    },
    {

      label: "Small",
      option_id: "2"
    }
  ],
  [{
      label: "Red",
      option_id: "1"
    },
    {
      label: "Large",
      option_id: "2"
    }
  ]
];



let k = options.map(function(item) {
  return item.reduce(function(acc, curr) {
    acc.label = `${acc.label} ${curr.label}`.trim();
    acc.option_id.push(curr.option_id)

    return acc;
  }, {
    label: '',
    option_id: []
  })
});

console.log(k)


1
您可以使用map()reduce()

const options = [
  [
    {
      label: "Blue",
      option_id: "1"
    },
    {

      label: "Small",
      option_id: "2"
    }
  ],
  [
    {
      label: "Red",
      option_id: "1"
    },
    {
      label: "Large",
      option_id: "2"
    }
  ]
];

const result = options.map((x) => {
  let label = x.reduce((acc, val) => { 
    acc.push(val.label);
    return acc;
  }, []).join(',');
  let optArr = x.reduce((acc, val) => { 
    acc.push(val.option_id);
    return acc;
  }, []);
  return {
    label: label,
    option_id: optArr
  }
});

console.log(result);


1

您可以始终采用迭代方式,首先使用带有编号的for循环编写该内容:

const options = [[{label: "Blue",option_id: "1"},{label: "Small",option_id: "2"}],
                 [{label: "Red",option_id: "1"},{label: "Large",option_id: "2"}]];
  
const result = [];
for(var i=0; i<options.length; i++){
  var arr = options[i];
  var labels = [];
  var ids = [];
  for(var j=0; j<arr.length; j++){
    var opt = arr[j];
    labels.push(opt.label);
    ids.push(opt.option_id);
  }
  result.push({label:labels.join(" "),option_id:ids});
}
console.log(result);

然后使用forEach丢弃索引。

const options = [[{label: "Blue",option_id: "1"},{label: "Small",option_id: "2"}],
                 [{label: "Red",option_id: "1"},{label: "Large",option_id: "2"}]];
  
const result = [];
options.forEach(arr => {
  var labels = [];
  var ids = [];
  arr.forEach(opt => {
    labels.push(opt.label);
    ids.push(opt.option_id);
  });
  result.push({label:labels.join(" "),option_id:ids});
});
console.log(result);

然后外部循环可以轻松地进行 map 处理:

const options = [[{label: "Blue",option_id: "1"},{label: "Small",option_id: "2"}],
                 [{label: "Red",option_id: "1"},{label: "Large",option_id: "2"}]];
  
const result = options.map(arr => {
  var labels = [];
  var ids = [];
  arr.forEach(opt => {
    labels.push(opt.label);
    ids.push(opt.option_id);
  });
  return {label:labels.join(" "),option_id:ids};
});
console.log(result);

尝试减少内部循环:

const options = [[{label: "Blue",option_id: "1"},{label: "Small",option_id: "2"}],
                 [{label: "Red",option_id: "1"},{label: "Large",option_id: "2"}]];
  
const result = options.map(arr => 
  (lists => ({label:lists.labels.join(" "),option_id:lists.ids}))
  (arr.reduce((lists,opt) => {
    lists.labels.push(opt.label);
    lists.ids.push(opt.option_id);
    return lists;
  },{labels:[],ids:[]}))
);
console.log(result);

arr.reduce”是这里“lists =>”函数的一个参数(它替换了之前代码片段中简单的“return”行)。我只想保留“join”,但这种方式可能有点过度。因此,保留一个显式变量也没有问题。”

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