使用Clojurescript中的变异

too*_*ays 2 json d3.js clojurescript

我正在通过尝试使用d3.js从JSON结构中绘制一些网格来学习Clojurescript的工作原理.我正在使用笔画来访问d3.

JSON看起来像这样:

[[{"players":{"0":{"rep":0},"1":{"rep":0}}},{"players":{"0":{"rep":0},"1":{"rep":0}}},
  {"players":{"0":{"rep":0},"1":{"rep":0}}},{"players":{"0":{"rep":0},"1":{"rep":0}}}],
 [{"players":{"0":{"rep":0},"1":{"rep":0}}},{"players":{"0":{"rep":0},"1":{"rep":0}}},
  {"players":{"0":{"rep":0},"1":{"rep":0}}},{"players":{"0":{"rep":0},"1":{"rep":0}}}],
 [{"players":{"0":{"rep":0},"1":{"rep":0}}},{"players":{"0":{"rep":0},"1":{"rep":0}}},
  {"players":{"0":{"rep":0},"1":{"rep":0}}},{"players":{"0":{"rep":0},"1":{"rep":0}}}],
 [{"players":{"0":{"rep":0},"1":{"rep":0}}},{"players":{"0":{"rep":0},"1":{"rep":0}}}, 
  {"players":{"0":{"rep":0},"1":{"rep":0}}},{"players":{"0":{"rep":0},"1":{"rep":0}}}]]
Run Code Online (Sandbox Code Playgroud)

它代表一个4乘4的网格.我正在尝试向单元格添加值,例如高度,宽度,x和y坐标,这样就可以将数据传递给d3进行绘制.

例如,它看起来像这样:

[[{"width":32,"height":32,"x":0,"y":0,"value":{"players":{"0":{"rep":0},"1":{"rep":0}}}},
  {"width":32,"height":32,"x":32,"y":0,"value":{"players":{"0":{"rep":0},"1":{"rep":0}}}},...
Run Code Online (Sandbox Code Playgroud)

通常我会使用转换函数映射结构,以将单元格从当前值转换为新形式,但这种方法似乎不起作用.我试过map-indexed: (map-indexed #(doto %2 (aset "width" %1)) row)但这似乎没有正确转换值.我很可能错误地访问或设置了值.

代码的当前迭代如下所示:

(defn board->grid [grid-width grid-height board square]
  (let [x-length (count board)
        y-length (count (first board))
        same (min (/ grid-width x-length) (/ grid-height y-length))
        grid-item-width (if square same (/ grid-width x-length))
        grid-item-height (if square same (/ grid-height y-length))
        start-x (/ grid-item-width 2)
        start-y (/ grid-item-height 2)
        values (array)
        grid (array)
        data (js->clj board :keywordize-keys true)]
        (doseq [x (range x-length)
                y (range y-length)]
          (let [current-cell (aget data y x)]
          (.log js/console (apply str (aset (aget data y x) "a" "b")))
          (.push grid (aget data y x))))
        (.text ($ :#status) grid)))
Run Code Online (Sandbox Code Playgroud)

任何帮助,将不胜感激!或者更好的是,更好的方法的建议,我不禁感到我正在做这个稍微错误!

Fra*_*ila 5

在clojure和clojurescript中使用可变性的基本经验法则是"不要".JS数组和对象没有实现函数依赖的大多数协议来完成它们的工作.例如,普通的js数组是不可序的!使用不可变数据结构完成大部分工作,并仅在需要与其他库接口时转换为可变等效项.

还有一些附加的功能,这是阵列特异性:into-array,to-array,aget,aset,amap,areducealength.(见这个备忘单.)

也有许多封闭的库函数您可能会发现有用的goog.array,goog.object或者goog.structs如果你想坚持使用可变数据结构.(请记住,clojurescript包含谷歌闭包库!)

您也可以在任何地方使用此表单:

(defn amap2d [arr f]
  (doseq [x (range (alength arr))
          y (range (alength (aget A x)))
         :let [cell (aget A y x)]]
    (f x y cell)))
Run Code Online (Sandbox Code Playgroud)

但我认为你会更乐意做js->clj,处理数据,然后clj->js就把它传递给d3.