简体   繁体   English

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

[英]Flatten array, but using sub-array as basis

We are trying to take an array that has this format: 我们正在尝试采用以下格式的数组:

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

and flatten it so it is expressed as: 并将其展平,表示为:

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

We are hoping that there is a more elegant way to transform this data using pre-existing library such as Ramda or Lodash, however any javascript implementation would be fine. 我们希望有一种更优雅的方法来使用预先存在的库(如Ramda或Lodash)来转换此数据,但是任何JavaScript实现都可以。

You could use reduce() and map() methods and return new array. 您可以使用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) 

With ES6, you can use nested Array.map() calls and flatten the resulting sub-arrays by spreading into Array.concat() : 使用ES6,您可以使用嵌套的Array.map()调用,并通过扩展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); 

 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)); 

Another approach to this is to use R.chain , which effectively maps the provided function over the list to produce a list of lists and then flattens the result. 另一种解决方法是使用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> 

At some point in the future you will likely be able to make use of the proposed Array.prototype.flatMap instead of R.chain . 在将来的某个时候,您可能可以使用建议的 Array.prototype.flatMap而不是R.chain

You can also use reduce() , the spread operator , map() and Object.assign() you can achieve your required result. 您还可以使用reduce()spread operatormap()Object.assign()来实现所需的结果。

DEMO 演示

 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); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM