Clojure 是否可以使用拉链操纵嵌套贴图的向量?
我需要通过应用以下两条规则将以下输入转换为输出:Clojure 是否可以使用拉链操纵嵌套贴图的向量?,clojure,Clojure,我需要通过应用以下两条规则将以下输入转换为输出: 删除最后一项为“nope”的所有向量 删除每个没有至少一个向量且最后一项为“ds1”的映射 (def输入 [{:simple1[:from[:simple1'ds1]]} {:simple2[:来自任何[:simple2'否][:simple2'ds1]]] {:walk1[:from[:sub1:sub2'ds1]} {:未受影响的[:from[:未受影响的'nope]} {:替换为nil[:from[:原始'ds1]]} {:concat1[
(def输入
[{:simple1[:from[:simple1'ds1]]}
{:simple2[:来自任何[:simple2'否][:simple2'ds1]]]
{:walk1[:from[:sub1:sub2'ds1]}
{:未受影响的[:from[:未受影响的'nope]}
{:替换为nil[:from[:原始'ds1]]}
{:concat1[:concat[:simple1'ds1][:simple2'ds1]]}
{:查找字[:查找[:word'word:word'ds1]]}])
(def输出
[{:simple1[:from[:simple1'ds1]]}
{:simple2[:来自任何[:simple2'ds1]]]}
{:walk1[:from[:sub1:sub2'ds1]}
{:替换为nil[:from[:原始'ds1]]}
{:concat1[:concat[:simple1'ds1][:simple2'ds1]]}
{:查找字[:查找[:word'word:word'ds1]]}])
我想知道使用zippers是否可以执行此转换?我建议使用这种通用树转换。要获得正确的替换函数可能需要一些修改,但它可以很好地与Clojure数据结构的任何嵌套配合使用,而在基于拉链的方法中,AFAIK可能更具挑战性
我们希望缩小我们的树,所以postwark
是我的目标。它接受一个函数f
和一个树根,然后遍历树,用(f leaf)
替换每个叶值,然后替换它们的父项和它们的父项等,直到最后替换根。(prewalk
与之类似,但从根开始,一直到叶子,所以通常通过拆分树枝来生长树木更为自然。)这里的策略是以某种方式构造一个函数,该函数修剪满足删除条件的任何分支,但返回任何其他值不变
(ns shrink-tree
(:require [clojure.walk :refer [postwalk]]))
(letfn[(rule-1 [node]
(and (vector? node)
(= 'nope (last node))))
(rule-2 [node]
(and
(map? node)
(not-any? #(and (vector? %) (= 'ds1 (last %)))
(tree-seq vector? seq (-> node vals first)))))
(remove-marked [node]
(if (coll? node)
(into (empty node) (remove (some-fn rule-1 rule-2) node))
node))]
(= output (postwalk remove-marked input)))
;; => true
在这里,fnsrule-1
和rule-2
尝试将规则转换为谓词,并删除标记的
:
rule1
或rule2
的任何成员。为了同时检查其中一个,我们将谓词与一些fn结合起来李>
'ds1
或:等
<>你可能也想考虑一下。它通过允许你选择和变换任意复杂的结构来支持这些变换。你能在你的文章中再加一些细节,让你考虑拉链来解决这个问题吗?简短的答案是肯定的。我惊讶的是没有人提到这个问题实际上不是在走一个地图矢量。使用向量值。示例数据中的所有映射都有一个键,该键与所讨论的过滤无关。因此,向量中的每个映射(迭代)都可以通过一个谓词提供,该谓词遍历任意嵌套的向量向量。我建议编辑问题并更新标题。