clojure - 在 Clojure 中使用二维数组的最佳实践?

标签 clojure multidimensional-array

我正在构建一个扫雷游戏,其中游戏板是一个二维数组。

要生成棋盘,我需要获取一个二维数组,随机放置一些炸弹,计算每个字段的所有相邻炸弹,然后将所有炸弹与另一个值(已显示)一起打包到一个 Map 中,该 Map 应该是最终值每个字段。

似乎要做这一切,我需要像map、filter、nth或zip这样的函数的帮助,但它们不应该处理列表,而应该处理二维数组。我已经开始构建这些,但这似乎是错误的道路。

是否有一些很酷的抽象可以帮助我使用二维数组上的现有函数?或者是否已经存在任何处理二维数组的函数?

编辑:我这样做的方式 - 在思考之前,应该有更好的方法 - 是这样的:

(defn mapmap [f xxs]
  (for [xs xxs]
    (map f xs)))

(defn mapmap-coords [f xxs]
  (for [[i xs] (map-indexed list xxs)]
    (map-indexed (fn [j x] (f j i)) xs)))

(defn get-value [board x y]
  (if (or (< x 0) (< y 0) (< (dec (count board)) y))
    false
    (let [xs (nth board y)]
      (if (< (dec (count xs)) x)
        false
        (nth xs x)))))

最佳答案

for 适用于嵌套顺序数据。

user> (def game-state
       (let [game '[[_ _ _ _]
                    [1 1 _ _]
                    [! 1 _ _]
                    [1 1 _ _]]]
         (for [[i row] (map-indexed list game)
               [j cell] (map-indexed list row)
               :when (not= '_ cell)]
              {:x i :y j :value cell})))
#'user/game-state
user> (pprint game-state)
({:x 1, :y 0, :value 1}
 {:x 1, :y 1, :value 1}
 {:x 2, :y 0, :value !}
 {:x 2, :y 1, :value 1}
 {:x 3, :y 0, :value 1}
 {:x 3, :y 1, :value 1})
nil

我们可以使用reduce再次构建数据结构(当然,任何状态转换都可以在两者之间完成)。

user> (let [empty-game (vec (repeat 4 '[_ _ _ _]))
            fill-cell (fn [game, {:keys [x y value]}] (assoc-in game [x y] value))
            game (reduce   fill-cell empty-game game-state)]
        (doseq [row game] (apply println row)))
_ _ _ _
1 1 _ _
! 1 _ _
1 1 _ _
nil

关于clojure - 在 Clojure 中使用二维数组的最佳实践?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25981155/

相关文章:

loops - 如何在clojure中的每一行打印数字列表?

java - PowerMock 可以在没有注释的情况下使用吗?

Clojure:使用哪个网站来搜索 "Function that does X"

java - 将二维数组的行返回为给定行号的逗号分隔字符串 Java

c++ - 逐个字符地添加字符串到 2dim 数组中

java - 多维数组 : Variable length row?

Clojure 传感器行为

clojure - clj-time.coerce java.sql.Date .toString 递减日期?

php - 按一个列值对行数据进行分组,并使用另一列值填充每组中的子数组

java - 如何编写用户输入的二维数组?