是否有一种简单的方法可以收集满足谓词的所有结构?
(./pull '[com.rpl/specter "1.0.0"])
(use 'com.rpl.specter)
(def data {:items [{:name "Washing machine"
:subparts [{:name "Ballast" :weight 1}
{:name "Hull" :weight 2}]}]})
(reduce + (select [(walker :weight) :weight] data))
;=> 3
(select [(walker :name) :name] data)
;=> ["Washing machine"]
Run Code Online (Sandbox Code Playgroud)
我们怎样才能获得所有的价值:名称,包括["镇流器""船体"]?
这是一种方法,使用recursive-path和stay-then-continue来完成实际工作。(如果省略:name路径参数中的最后一个select,您将获得完整的 \xe2\x80\x9citem / 部分映射 \xe2\x80\x9d 而不仅仅是字符串:name。)
(def data\n {:items [{:name "Washing machine"\n :subparts [{:name "Ballast" :weight 1}\n {:name "Hull" :weight 2}]}]})\n\n(specter/select\n [(specter/recursive-path [] p\n [(specter/walker :name) (specter/stay-then-continue [:subparts p])])\n :name]\n data)\n;= ["Washing machine" "Ballast" "Hull"]\nRun Code Online (Sandbox Code Playgroud)\n\n更新:为了回答下面的评论,这里是上面的一个版本,它下降到树的任意分支,而不是仅下降到:subparts任何给定节点的分支,排除:name(这是树中值的键)我们想要提取并且本身不应该被视为分支点):
(specter/select\n [(specter/recursive-path [] p\n [(specter/walker :name)\n (specter/stay-then-continue\n [(specter/filterer #(not= :name (key %)))\n (specter/walker :name)\n p])])\n :name]\n ;; adding the key `:subparts` with the value [{:name "Foo"}]\n ;; to the "Washing machine" map to exercise the new descent strategy\n (assoc-in data [:items 0 :subparts2] [{:name "Foo"}]))\n\n;= ["Washing machine" "Ballast" "Hull" "Foo"]\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
555 次 |
| 最近记录: |