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