如何通过Lodash拆分包含另一个数组的对象数组

时间:2017-04-27 13:43:40

标签: javascript arrays json collections lodash

我有这个数组:[{ name: "A1", arr: [1,2] }, { name: "A2", arr: [1] }]

如何将第一个对象拆分为两个只包含一个数组值的对象?

结果应为:

[{name: "A1", arr: [1] }, {name: "A1", arr: [2]}, {name: "A2", arr: [1] }]

我没有在lodash文档中找到任何可以帮助解决此问题的通用工具。 (实际上我使用lodash非常罕见,所以这就是我要求帮助我的原因)。

感谢您的帮助!

5 个答案:

答案 0 :(得分:2)

以下是使用#Array.reduce函数的方法:

[{ name: "A1", arr: [1,2] }, { name: "A2", arr: [1] }].reduce((acc, val) => {
   val.arr.forEach(el => {
     acc.push({name: val.name, arr: [el]});
   });
   return acc;
}, [])

编辑

@Ian Segers建议使用mapconcat(谢谢):

[{ name: "A1", arr: [1,2] }, { name: "A2", arr: [1] }].reduce((acc, val) => 
  acc.concat(val.arr.map(el => {
     return  {name: val.name, arr: [el]}
   })), [])

致以最诚挚的问候,

答案 1 :(得分:1)

假设属性是静态的,您可以使用以下解决方案。

var arr = [{ name: "A1", arr: [1,2] }, { name: "A2", arr: [1] }], res = [];
    arr.forEach(v => v.arr.length > 1 ? v.arr.forEach(c => res.push({name: v.name, arr: [c]})) : res.push(v));
    
    console.log(JSON.stringify(res));

答案 2 :(得分:1)

您可以在对象中映射数组的项目,并将外部名称属性映射到新的结果集,因为fadeToggle() ryeballar的答案建议。

.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
var data = [{ name: "A1", arr: [1, 2] }, { name: "A2", arr: [1] }],
    result = data.reduce(
        (r, a) => r.concat(a.arr.map(b => Object.assign({}, a, { arr: [b] })))
    , []);

console.log(result);

ES6与Flatten an nested array of objects using Lodash

.as-console-wrapper { max-height: 100% !important; top: 0; }
Write-Host

答案 3 :(得分:1)

通常情况下,我想采用.reduce()方式,但这在概念上是错误的。这是错误的,因为减少是为了减少,如果我们使用它进行扩展,那么我们必须使用副作用,这不是一个正确的功能方法。然而......在JS中,没有功能工具来处理这类任务。

所以只是为了好玩而发明一个。 Array.unfold()

Arrays.unfold(p,f,t,v)有4个参数。

  • p 这是一个定义停止位置的功能。 p函数需要3个参数,就像许多数组函子一样。值,索引和当前结果数组。它应返回一个布尔值。当它返回true时,递归迭代停止。
  • f 这是一个返回下一项功能值的函数。
  • t 这是一个函数,用于在下一回合中将下一个参数返回到f
  • s 是用于通过f计算索引0的舒适座位的种子值。

现在我们可以为所需的情况实现我们的展开Array构造函数。

&#13;
&#13;
Array.unfold = function(p,f,t,s){
  var res = [],
   runner = v =>  p(v,res.length-1,res) ? [] : (res = res.concat(f(v)), runner(t(v)), res);
  return runner(s);
};

var data   = [{ name: "A1", arr: [1,2] }, { name: "A2", arr: [1] }],
    result = Array.unfold(v => v.length === 0,
                          v => v[0].arr.map(n => Object.assign({},v[0],{arr:[n]})),
                          v => v.slice(1),
                          data);
console.log(JSON.stringify(result));
&#13;
&#13;
&#13;

答案 4 :(得分:1)

使用Array#map循环数据,使用第二个Array#map创建单独的对象,然后通过展开结果并在其上使用Array#concat来展平它们:

&#13;
&#13;
var data = [{ name: "A1", arr: [1,2] }, { name: "A2", arr: [1] }];

var result = [].concat(...data.map((item) => item.arr.map((num) => Object.assign({}, item, { arr: [num] }))));

console.log(result);
&#13;
&#13;
&#13;