【问题标题】:Clojure, using arguments in matchingClojure,在匹配中使用参数
【发布时间】:2014-05-30 01:01:55
【问题描述】:

所以我有一个类似{[1 1 1] "a" [1 1 2] "b"} 等的地图。我有一个类似的函数:

(defn fetch [map x y z]
  (select-keys map (into []  (for [[k v] map
                                   :when (match/match [k]
                                                      [[x y z]] true
                                                      :else false)]
                               k))))

这似乎不起作用。它似乎只有在我硬编码xyz 的值时才有效。有什么建议么?我想要一些可以提供任意数量的参数的东西,它会给我所有匹配的键,但我想不通。

【问题讨论】:

  • 请包括您的预期输出。
  • 如果您对match 心动,您可以写(match [k [x y z]] [[a b c] [a b c]] true) 之类的内容。但这肯定看起来很傻。

标签: map clojure arguments match


【解决方案1】:

如果你打算

(fetch {[1 1 1] "a" [1 1 2] "b"} 1 1 1)

返回

{[1 1 1] "a"},

那么过滤输入图的整个key seq是极其浪费的:

(conj {} (find {[1 1 1] "a" [1 1 2] "b"} [1 1 1]))

将正确有效地完成工作。

如果您想使用更有趣的标准从地图中选择条目,则可以对其进行过滤并使用into {} 将结果倒入新地图中:

(into {} (filter (fn [[k v]] (even? k)) {0 "a" 1 "b" 2 "c" 3 "d"}))
;= {0 "a", 2 "c"}

for:when 实际上是一回事,所以如果你喜欢这种语法,当然可以使用它。你只需要提供一个谓词来做你想做的事。这应该比使用带有过滤密钥序列的select-keys 更高效。

对于给定坐标值的任意地图从地图中选择键,您可以使用

(defn fetch
  "Takes a map `m` keyed by vectors and a map `coords`
  keyed by indices into those vectors.

  Returns a submap of `m` that includes all on only the keys
  which agree with `coords` on the indices mentioned in `coords`."
  [m coords]
  (into {}
    (for [[k :as e] m
          :when (every? #(= (nth k %) (get coords %))
                  (keys coords))]
      e)))

(fetch {[1 1 1] "a" [1 1 2] "b" [1 2 1] "c"} {0 1 1 1})
;= {[1 1 1] "a", [1 1 2] "b"}

至于你的match 表单不起作用:match 是一个绑定表单,所以如果你在模式中引入变量,如果它与模式匹配,它们将绑定到从输入中提取的值,可能会从外部隐藏本地人范围。

【讨论】:

  • 没错,如果我只想要一个参数会很浪费,但我希望它返回与模式匹配的所有键的子图,所以 (fetch {[1 1 1] "a" [1 1 2] "b"} 1 1) 将返回 "a" 和 "b"。所以对于匹配,你的意思是 [x y z] 被绑定到 k 中的任何内容?
  • 是的,回复:[x y z] 绑定到 k 的元素。此外,模式[x y z] 匹配任意三元素向量。例如,如果您替换模式中的实际值并匹配[1 2 3],那么该模式当然只会匹配[1 2 3] 的确切值。我将在一秒钟内根据更有趣的标准通过评论从地图中选择键来更新答案。
  • 已更新。继续上面的内容,您的评论包括对fetch 的调用,只有三个参数,但是您在问题文本中对fetch 的草图不支持该数量,并且不清楚您将如何确定模式应该被认为是对应的。
  • 更新了fetch 的工作实现,它需要一个要过滤的地图和另一个指导过滤的地图。
猜你喜欢
  • 2016-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多