[英]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 operator
, map()
和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.