Javascript 如何使用Ramda将数组数组转换为对象数组? 背景
我有一个数组,表示具有以下格式的网格:Javascript 如何使用Ramda将数组数组转换为对象数组? 背景,javascript,arrays,functional-programming,ramda.js,Javascript,Arrays,Functional Programming,Ramda.js,我有一个数组,表示具有以下格式的网格: 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 = [
[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.map
和R.chain
it。但是我有一个主要问题:ramda函数不将索引作为参数(与JavaScript中的计数器实现不同)
所以我相信用ramda做这个练习是不可能的
问题:
有没有一种方法可以只使用ramda函数(不适用于循环)进行此练习?一个简单的嵌套循环可以:
const result = [];
for(const [row, content] of grid.entries()) {
for(const [column, value] of content.entries()) {
result.push({ row, column, value });
}
}
一个简单的嵌套循环可以:
const result = [];
for(const [row, content] of grid.entries()) {
for(const [column, value] of content.entries()) {
result.push({ row, column, value });
}
}
正如在评论中所讨论的:这是一个没有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}]),[]);
控制台日志(结果)代码>如注释中所述:这是一个没有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}]),[]);
控制台日志(结果)代码>解决方案
使用@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 ) ],
[ ]
);
解决方案
使用@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的另一种方法是映射行以添加其列索引,然后是网格,然后再次映射以向每个列添加行索引
const grid=[
[null,null,null,null,null,null,null,null],
[null,null,null,null,null,null,null,null],
[null,“”,null,null,null,null,“”],
[“?”、“?”、空、空、“?”、“?”、“?”],
["®" , "®" , "®" , "©" , "®" , "©" , "©" ],
["®" , "©" , "©" , "®" , "©" , "®" , "©" ],
];
常量mapCol=R.addIndex(R.map)(R.flip(R.assoc('column'))
常量映射行=R.addIndex(R.map)(R.flip(R.assoc('row'))
常量mapVal=R.map(R.objOf('value'))
常数fn=R.管道(
R.map(mapVal),//将每个值转换为`{value:…}`
R.map(mapCol),//添加列索引`{value:…,column:n}`
R.transpose,//对整个网格进行转置
R.chain(mapRow)//添加行索引`{value:…,column:n,row:m}`
)
console.log(fn(网格))
使用Ramda的另一种方法是映射行以添加其列索引,然后映射网格,然后再次映射以向每个列添加行索引
const grid=[
[null,null,null,null,null,null,null,null],
[null,null,null,null,null,null,null,null],
[null,“”,null,null,null,null,“”],
[“?”、“?”、空、空、“?”、“?”、“?”],
["®" , "®" , "®" , "©" , "®" , "©" , "©" ],
["®" , "©" , "©" , "®" , "©" , "®" , "©" ],
];
常量mapCol=R.addIndex(R.map)(R.flip(R.assoc('column'))
常量映射行=R.addIndex(R.map)(R.flip(R.assoc('row'))
常量mapVal=R.map(R.objOf('value'))
常数fn=R.管道(
R.map(mapVal),//将每个值转换为`{value:…}`
R.map(mapCol),//添加列索引`{value:…,column:n}`
R.transpose,//对整个网格进行转置
R.chain(mapRow)//添加行索引`{value:…,column:n,row:m}`
)
console.log(fn(网格))
<代码> <代码>您是否考虑使用香草JS?我不知道ramda,但是我很确定你可以用vanilla JS获得一个干净的Functional版本来获得你的预期输出。如果问题是缺少索引,我想你可以用你需要的索引来装饰它?大多数功能语言都有类似的功能,如斯卡拉中的<>代码> ZIPouthCudio。我不熟悉RAMDA,但它也有。您考虑使用香草JS吗?我不知道ramda,但是我很确定你可以用vanilla JS获得一个干净的Functional版本来获得你的预期输出。如果问题是缺少索引,我想你可以用你需要的索引来装饰它?大多数函数式语言都有类似的功能,比如Scala中的zipWithIndex
。我不熟悉ramda,但它也有。请允许我重复所问的问题:是否有一种方法可以仅使用ramda函数来做此练习(对于循环,否)?请允许我重复所提出的问题:是否有一种方法可以只使用ramda函数(不使用for循环)进行此练习?我非常清楚在没有ramda的情况下进行此练习的可能性。这不是问题所在。挑战在于使用它:我非常清楚在没有拉姆达的情况下使用它的可能性。这不是问题所在。挑战在于如何使用它:P