将二维数组的二维网格展平为单个二维数组,在 JavaScript 中(功能上?)
Flattening 2D grid of 2D arrays into a single 2D array, in JavaScript (functionally?)
我正在开发的游戏有一个二维数组(块)的二维数组(网格):
const c1 = [[1, 2],
[3, 4]]
const c2 = [[5, 6],
[7, 8]]
const c3 = [[9, 0],
[1, 2]]
const c4 = [[3, 4],
[5, 6]]
const grid_of_chunks = [[c1, c2],
[c3, c4]];
我想 reduce/flatten grid_of_chunks
到:
[[1, 2, 5, 6],
[3, 4, 7, 8],
[9, 0, 3, 4],
[1, 2, 5, 6]]
我已经能够为此实现一个函数式解决方案(在 Clojure 的 2 行中),但我正在努力将其转换为函数式 JavaScript,并弥合两者之间的差距两种语言的 map
语义(JS map 只接受一个数组,而 Clojure 的 map
接受许多集合...)。
据我所知:
function join_grid_of_chunks(gofc) {
const joined_horiz = gofc.map(
gofc_row => [].map.apply(gofc_row, [cs => [].concat.apply(cs)])
);
return [].concat.apply(joined_horiz);
}
编辑:Clojure 解决方案(适用于任意大小的方形网格中统一大小的方形块):
(defn join-grid-of-chunks [gofc]
(let [joined (map #(apply map concat %) gofc)]
(apply concat joined)))
这是我的:
const c1 = [[1, 2], [3, 4]];
const c2 = [[5, 6], [7, 8]];
const c3 = [[9, 0], [1, 2]];
const c4 = [[3, 4], [5, 6]];
const grid_of_chunks = [
[c1, c2],
[c3, c4]
];
function transform(input) {
return input.flatMap(rows => {
return rows.reduce((result, chunk) => {
chunk.forEach((row, rowIndex) => {
result[rowIndex] = result[rowIndex] || [];
result[rowIndex].push(...row);
});
return result;
}, []);
});
}
console.log(transform(grid_of_chunks));
应该适用于 NxN 块和 MxM 网格
使用 flatMap
的更通用的解决方案是映射每个网格行的第一个块的索引。
function joinGridOfChunks(grid) {
return grid.flatMap(row => row[0].map((_, i) => row.flatMap(chunk => chunk[i])))
}
使用 zip
函数(例如 lodash 中的函数),您可以稍微优雅地编写它:
function zip(...arrays) {
return arrays[0].map((_, i) => arrays.map(arr => arr[i]))
}
function joinChunks(chunks) { // Horizontally join an array of chunks e.g. [[[1,2],[3,4]], [[5,6],[7,8]]] --> [[1,2,5,6],[3,4,7,8]]
return zip(...chunks).map(row => row.flat())
}
console.log(gridOfChunks.flatMap(joinChunks));
zip
加上 map
似乎接近 Clojure 的 map
与多个集合。这应该适用于二维网格中的任何形状的二维块。
我正在开发的游戏有一个二维数组(块)的二维数组(网格):
const c1 = [[1, 2],
[3, 4]]
const c2 = [[5, 6],
[7, 8]]
const c3 = [[9, 0],
[1, 2]]
const c4 = [[3, 4],
[5, 6]]
const grid_of_chunks = [[c1, c2],
[c3, c4]];
我想 reduce/flatten grid_of_chunks
到:
[[1, 2, 5, 6],
[3, 4, 7, 8],
[9, 0, 3, 4],
[1, 2, 5, 6]]
我已经能够为此实现一个函数式解决方案(在 Clojure 的 2 行中),但我正在努力将其转换为函数式 JavaScript,并弥合两者之间的差距两种语言的 map
语义(JS map 只接受一个数组,而 Clojure 的 map
接受许多集合...)。
据我所知:
function join_grid_of_chunks(gofc) {
const joined_horiz = gofc.map(
gofc_row => [].map.apply(gofc_row, [cs => [].concat.apply(cs)])
);
return [].concat.apply(joined_horiz);
}
编辑:Clojure 解决方案(适用于任意大小的方形网格中统一大小的方形块):
(defn join-grid-of-chunks [gofc]
(let [joined (map #(apply map concat %) gofc)]
(apply concat joined)))
这是我的:
const c1 = [[1, 2], [3, 4]];
const c2 = [[5, 6], [7, 8]];
const c3 = [[9, 0], [1, 2]];
const c4 = [[3, 4], [5, 6]];
const grid_of_chunks = [
[c1, c2],
[c3, c4]
];
function transform(input) {
return input.flatMap(rows => {
return rows.reduce((result, chunk) => {
chunk.forEach((row, rowIndex) => {
result[rowIndex] = result[rowIndex] || [];
result[rowIndex].push(...row);
});
return result;
}, []);
});
}
console.log(transform(grid_of_chunks));
应该适用于 NxN 块和 MxM 网格
使用 flatMap
的更通用的解决方案是映射每个网格行的第一个块的索引。
function joinGridOfChunks(grid) {
return grid.flatMap(row => row[0].map((_, i) => row.flatMap(chunk => chunk[i])))
}
使用 zip
函数(例如 lodash 中的函数),您可以稍微优雅地编写它:
function zip(...arrays) {
return arrays[0].map((_, i) => arrays.map(arr => arr[i]))
}
function joinChunks(chunks) { // Horizontally join an array of chunks e.g. [[[1,2],[3,4]], [[5,6],[7,8]]] --> [[1,2,5,6],[3,4,7,8]]
return zip(...chunks).map(row => row.flat())
}
console.log(gridOfChunks.flatMap(joinChunks));
zip
加上 map
似乎接近 Clojure 的 map
与多个集合。这应该适用于二维网格中的任何形状的二维块。