1

次のようなセルの配列を含むボード構造を持つボード ゲームをモデル化するリフレーム アプリを作成しています。

{... :board-cells [{:name "cell-1" :material #object} {:name "cell-2" :material #object} ...]}

リフレームは のような素敵なキーワード構文で「自然な」部分構造の取得をサポートしてい(db :board-cells)ますが、マテリアルを取得するたびに「ドリルダウン」クエリ全体を書かなければならないことにうんざりしています(get (nth (db :board-cells) index) :material)。これには、データベースの物理レイアウトがアプリケーション ロジックに密接に結合されるという欠点もあります。データベース構造を変更することにした場合はどうなりますか? 次に、1 つではなく 10 の異なるスポットを更新する必要があります。

「仮想クエリ」を作成する公式のリフレーム方法はありますか? (db :get-nth-mat n)n はboard-cells配列内のセル番号です。と思っていdb.cljsreg-subところだったのですが、うまくいかないようです。はい、独自のゲッターを作成できます。

(defn get-material [db index]
  (get (nth (db :board-cells) index) :material))

のように呼び出します(println "mat-4=" (cell/get-material db 4))が、これはそれほど便利でも素敵でもありません(db :get-nth-mat n)

どうもありがとう。

4

1 に答える 1

1

dbは単なるマップであり、この「機能」はリフレームとは関係ありませんが、すべてのマップは機能であり、キーワードでもあります。だからあなたがするとき、(map something)または(:keyword something)あなたが実際にやっている (get map something)とき(get something :keyword).

したがって、データに異なる方法でアクセス/反復する以外に「近道」は実際にはありません (例: 、、、doseq... ) - セルごとにグリッド セルをレンダリングしようとしていると仮定します。このようにして、インデックスベースのアクセスをまったく取り除きます。formap

それ以外の場合は、あなたのような専用関数を使用しますが、むしろ名前を付けたいと思います(オブジェクト指向でmaterial-by-idx関数getsetアクセサに名前を付けるのはかなりまれです(ただし、状態変更の設定などの場所があります))。

1 つのことを適切に行う適切な名前の、理想的には純粋な関数を持つことは、関数型および Lisp プログラミングの重要な構成要素です。そして、多くの場合、もう少し入力しなければならないことのマイナス面は、スレッド化や部分適用、または最後の手段としてマクロなどの高レベルのプログラミング パラダイムによって軽減できます。

get-inそして、それを少し整理するために使用できます:

(defn material-by-idx [db idx]
  (get-in db [:board-cells idx :material]))

たとえば、ループ内で次のようなものを使用できるようになりました。

(let [mat-at (partial material-by-idx db)]
  (mat-at 5))

ところで:あなたが望むバージョンは(db :get-nth-mat n)実際に動作します(しかし、あなたが望むようにはなりません)。にキーがない場合は 、 (get db :get-nth-mat n)(3 つの引数get)に変わります。n:get-nth-matdb

于 2020-01-03T09:28:11.257 に答える