繁体   English   中英

如何使用Ramda将数组数组转换为对象数组?

[英]How to transform array of arrays into an array of objects with Ramda?

背景

我有一个数组数组,表示具有以下格式的网格:

const grid = [
    [null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null],
    [null, "®" , null, null, null, null, "®" ],
    ["©" , "©" , null, null, "©" , "®" , "®" ],
    ["®" , "®" , "®" , "©" , "®" , "©" , "©" ],
    ["®" , "©" , "©" , "®" , "©" , "®" , "©" ],
];

目的

我的目标是将该数组转换为以下内容:

const grid = [ 
    { row: 0, column: 1, value: null},
    { row: 0, column: 2, value: null},
    { row: 0, column: 3, value: null},
    //... some rows after ...
    { row: 3, column: 0, value: "©"},
    // etc...
];

研究

我的第一个想法是使用两个嵌套的R.mapR.chain 但是我有一个主要问题:ramda函数将索引作为参数(与JavaScript中的计数器实现不同)。

因此,我相信使用ramda进行此练习是不可能的。

有没有办法仅使用ramda函数(没有for循环)来进行此练习?

正如评论中所讨论的:这是一个没有ramda,但也没有任何for循环的版本。

希望你会喜欢;)

如您所见,完全可以在没有任何for循环且没有ramda或其他lib之类的覆盖的情况下执行此操作。

 const grid = [ [null, null, null, null, null, null, null], [null, null, null, null, null, null, null], [null, "®" , null, null, null, null, "®" ], ["©" , "©" , null, null, "©" , "®" , "®" ], ["®" , "®" , "®" , "©" , "®" , "©" , "©" ], ["®" , "©" , "©" , "®" , "©" , "®" , "©" ], ]; const result = grid.reduce((r, array, i) => [...r, ...array.map((value, j) => ({row: i, column: j, value}))], []); console.log(result); 

使用@sjahan的解决方案使用Ramda的自然解决方案如下:

const R  require("ramda");
const mapIndexed = R.addIndex( R.map );
const reduceIndexed = R.addIndex( R.reduce );

const convertGrid = reduceIndexed(
  ( acc, array, i ) => [...acc, ...mapIndexed( ( value, j ) => ( { row: i, column: j, value } ), array ) ],
  [ ]
);

使用Ramda的另一种方法是在行上映射以添加其列索引,然后transpose网格,然后再次在其上映射以向每个列添加行索引。

 const grid = [ [null, null, null, null, null, null, null], [null, null, null, null, null, null, null], [null, "®" , null, null, null, null, "®" ], ["©" , "©" , null, null, "©" , "®" , "®" ], ["®" , "®" , "®" , "©" , "®" , "©" , "©" ], ["®" , "©" , "©" , "®" , "©" , "®" , "©" ], ]; const mapCol = R.addIndex(R.map)(R.flip(R.assoc('column'))) const mapRow = R.addIndex(R.map)(R.flip(R.assoc('row'))) const mapVal = R.map(R.objOf('value')) const fn = R.pipe( R.map(mapVal), // convert each value to `{ value: ... }` R.map(mapCol), // add the column index `{ value: ..., column: n }` R.transpose, // transpose the whole grid R.chain(mapRow) // add the row index `{ value: ..., column: n, row: m }` ) console.log(fn(grid)) 
 <script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script> 

R.chain的最后一次调用只需R.chain即可完成映射和展平。

请注意,这导致列表按列然后按行升序排列。 如果您需要按照示例将列表按行然后按列升序,则可以再次像这样对网格进行转置:

const fn = pipe(
  R.map(mapVal),
  R.map(mapCol),
  R.transpose,
  R.map(mapRow),
  R.transpose,
  R.unnest
)

一个简单的嵌套循环可以做到这一点:

 const result = [];

 for(const [row, content] of grid.entries()) {
    for(const [column, value] of content.entries()) {
       result.push({ row, column, value });
    }
}

暂无
暂无

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

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