在 JavaScript 中将 2D 数组的 2D 网格展平为单个 2D 数组(功能上?)

发布于 2025-01-13 09:00:27 字数 1167 浏览 5 评论 0原文

我有一个由 2D 数组(块)组成的 2D 数组(网格),用于我正在开发的游戏:

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]];

并且我想将 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)))

I have a 2D array (grid) of 2D arrays (chunks) for a game I'm developing:

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]];

and I want to reduce/flatten the grid_of_chunks to:

[[1, 2, 5, 6],
 [3, 4, 7, 8],
 [9, 0, 3, 4],
 [1, 2, 5, 6]]

I've been able to implement a functional solution for this (in 2 lines of Clojure), but I'm struggling to wrap my head around translating it to functional JavaScript, and bridging the gap between the two language's map semantics (JS map only accepts one array, whereas Clojure's map accepts many collections...).

This is as far as I got:

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);
}

Edit: Clojure solution (which works for uniformly-sized square chunks, in an arbitrarily sized square grid):

(defn join-grid-of-chunks [gofc]
  (let [joined (map #(apply map concat %) gofc)]
    (apply concat joined)))

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

烟酉 2025-01-20 09:00:27

使用 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。这应该适用于二维网格中任何形状的二维块。

A more general solution using flatMap is to map over the indices from the first chunk of each grid row.

function joinGridOfChunks(grid) {
    return grid.flatMap(row => row[0].map((_, i) => row.flatMap(chunk => chunk[i])))
}

With a zip function (such as the one in lodash), you could write it slightly more elegantly as:

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 plus map seems to be close to Clojure's map with multiple collections. This should work for any shape 2d chunks in a 2d grid.

不打扰别人 2025-01-20 09:00:27

这是我所拥有的:

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 网格

Here's what I have:

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));

Should work for NxN chunks and MxM grid

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文