Clojure:使用索引为向量中的每个元素调用一个函数

Jer*_*rks 26 loops vector clojure

说我有一个矢量:

(def data ["Hello" "World" "Test" "This"])
Run Code Online (Sandbox Code Playgroud)

我想在一个有api的地方填充一张桌子:

(defn setCell
  [row col value]
  (some code here))
Run Code Online (Sandbox Code Playgroud)

那么获得以下调用的最佳方法是什么:

(setCell 0 0 "Hello")
(setCell 0 1 "World")
(setCell 0 2 "Test")
(setCell 0 3 "This")
Run Code Online (Sandbox Code Playgroud)

我发现以下内容可行:

(let [idv (map vector (iterate inc 0) data)]
  (doseq [[index value] idv] (setCell 0 index value)))
Run Code Online (Sandbox Code Playgroud)

但是有没有更快的方法不需要新的临时数据结构idv?

Art*_*ldt 27

只需将索引与数据一起映射,您就可以以非常方便的方式获得相同的效果.

(map #(setCell 0 %1 %2) (iterate inc 0) data)
Run Code Online (Sandbox Code Playgroud)

您可能希望将其包装在一个(doall(doseq现在进行调用.将无限seq与有限seq一起映射就好了,因为当最短的seq用完时,map将停止.

  • 3年跟进:(iterate inc 0)更好用(范围)写 (10认同)

Rol*_*zzi 27

在游戏中有点晚,但访问此页面的人:现在(从clojure 1.2开始)map-indexedclojure.core中有一个功能.

一个问题(除非我弄错了):没有"pmap"等价,这意味着地图索引计算不能轻易并行化.在这种情况下,我会参考上面提供的解决方案.


Bri*_*per 10

你这样做的方式是惯用的(clojure.contrib.seq-utils/indexed事实上是相同的).如果您真的想避免额外的数据结构,可以这样做:

(loop [data data, index 0]
  (when (seq data)
    (setCell 0 index (first data))
    (recur (rest data) (inc index))))
Run Code Online (Sandbox Code Playgroud)

我会使用你的版本,除非有充分的理由不这样做.

  • Clojure 1.2添加了`map-indexed`,这是迄今为止我见过的最简单,最好的选项.请参阅下面的[Rollo答案](http://stackoverflow.com/a/5992602/109618). (5认同)

pmf*_*pmf 8

最好的方法是使用clojure.contrib.seq-utils/indexed,看起来像这样(使用解构):

(doseq [[idx val] (indexed ["Hello" "World" "Test" "This"])]
  (setCell 0 idx val))
Run Code Online (Sandbox Code Playgroud)