展平数组,但使用子数组作为基础

时间:2018-04-16 15:44:22

标签: javascript arrays lodash transformation ramda.js

我们正在尝试使用具有以下格式的数组:

[
{batchId: 123, files: [{fileName: 'fileA.txt'}, {fileName: 'fileB.txt'}],
{batchId: 456, files: [{fileName: 'fileC.txt'}, {fileName: 'fileD.txt'}],
]

并将其展平以表示为:

[
{batchId: 123, fileName: 'fileA.txt'},
{batchId: 123, fileName: 'fileB.txt'},
{batchId: 456, fileName: 'fileC.txt'},
{batchId: 456, fileName: 'fileD.txt'},
]

我们希望有一种更优雅的方法来使用预先存在的库(例如Ramda或Lodash)来转换这些数据,但是任何javascript实现都可以。

5 个答案:

答案 0 :(得分:2)

您可以使用reduce()map()方法并返回新数组。



const data = [
{batchId: 123, files: [{fileName: 'fileA.txt'}, {fileName: 'fileB.txt'}]},
{batchId: 456, files: [{fileName: 'fileC.txt'}, {fileName: 'fileD.txt'}]},
]

const result = data.reduce((r, e) => {
  r.push(...e.files.map(o => Object.assign({}, o, {batchId: e.batchId})))
  return r;
}, [])

console.log(result)




答案 1 :(得分:1)

使用ES6,您可以使用嵌套的Array.map()调用,并将生成的子数组按spreading展平为Array.concat()



const data = [{batchId: 123, files: [{fileName: 'fileA.txt'}, {fileName: 'fileB.txt'}]},{batchId: 456, files: [{fileName: 'fileC.txt'}, {fileName: 'fileD.txt'}]}];

const result = [].concat(...
  data.map(({ batchId, files }) => 
    files.map(({ fileName }) => ({ batchId, fileName })
  )));

console.log(result);




答案 2 :(得分:1)

var arr = [
    {batchId: 123, files: [{fileName: 'fileA.txt'}, {fileName: 'fileB.txt'}]},
    {batchId: 456, files: [{fileName: 'fileC.txt'}, {fileName: 'fileD.txt'}]},
];

function flatten(array) {
  return array.reduce(function(newArray, item) {
      return newArray.concat(item.files.map(function(file) { 
          return {
             batchId: item.batchId,
             fileName: file.fileName
          };
     }));
  }, []);
}

console.log(flatten(arr));

答案 3 :(得分:1)

另一种方法是使用R.chain,它有效地将提供的函数映射到列表上以生成列表列表,然后展平结果。



const data =
  [ {batchId: 123, files: [{fileName: 'fileA.txt'}, {fileName: 'fileB.txt'}]}
  , {batchId: 456, files: [{fileName: 'fileC.txt'}, {fileName: 'fileD.txt'}]}
  ]

const fn =
  R.chain(({batchId, files}) => R.map(R.assoc('batchId', batchId), files))

console.log(fn(data))

<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
&#13;
&#13;
&#13;

在将来的某个时候,您可能会使用proposed Array.prototype.flatMap代替R.chain

答案 4 :(得分:0)

您还可以使用reduce()spread operatormap()Object.assign()来获得所需的结果。

<强>样本

&#13;
&#13;
const arr = [{
  batchId: 123,
  files: [{
    fileName: 'fileA.txt'
  }, {
    fileName: 'fileB.txt'
  }]
}, {
  batchId: 456,
  files: [{
    fileName: 'fileC.txt'
  }, {
    fileName: 'fileD.txt'
  }]
}];


let result = arr.reduce((r, o) => {
  return [...r, ...o.files.map(v => {
    return Object.assign(v, {
      batchId: o.batchId
    });
  })];
}, []);

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