【问题标题】:destructure vector by index按索引解构向量
【发布时间】:2013-05-03 16:53:29
【问题描述】:

我想知道是否有办法按索引解构向量。基本上,一个可以让我避免的速记:

(defn f [v]
    (let [x (nth v 4)
          y (nth v 5)]
        (println x y)))

这是我的基本问题:

user=> (defn f [{x 4 y 5}] (println x y))
#'user/f
user=> (f [0 1 2 3 4 5 6])
4 5
nil
user=> (f (apply vector (range 10)))
4 5
nil
user=> (f (range 10))
5 nil
nil
user=>

【问题讨论】:

  • 您的问题因编辑而发生了显着变化。在任何情况下,(range 10) 是一个惰性序列,因此不是关联的,因此这不起作用。或者更确切地说,工作方式不同。有关更多详细信息,请参阅我的答案中的 cmets。
  • 所以,关于按索引解构向量的原始问题的答案是,是的,你可以做到;关于按索引解构序列的新问题的答案是你不能。

标签: clojure destructuring


【解决方案1】:

回答原来关于解构向量的问题:

向量是关联的,所以你可以使用关联解构:

(let [{x 4 y 5} [0 1 2 3 4 5 6]]
  [x y])
;= [4 5]

回应下面的评论,这适用于任何解构形式的工作,包括fn 参数列表:

((fn [{x 4 y 5}] [x y]) [0 1 2 3 4 5 6])
;= [4 5]

回答关于解构 seqs 的新问题:

如果您将 seq 传递给上述定义的函数来代替向量,则将应用 seq 的关联解构规则。即先将seq倒入一个hash map中——(range 10)在这个阶段变成{0 1 2 3 4 5 6 7 8 9}——然后这个hash map会被解构为一个map。

没有办法通过索引解构 seq。这是设计使然,因为 seq 不适用于需要快速随机访问的应用程序。

【讨论】:

  • 我想要函数参数列表中的解构,所以我可以避免 let。
  • 我在我的问题中添加了更多信息,这就是我最初提出问题的原因;也就是说,它仅在参数是向量时才有效。如果是列表,突然就不行了。
  • 这并不突然,列表不是关联的,并且地图解构以不同的方式对它们进行操作。具体来说,它们(和其他 seq 类型)首先被倒入一个新的哈希映射中,然后用于解构操作。
  • 这里的结果是(range 10)首先被转换为{0 1 2 3 4 5 6 7 8 9},然后这张地图被解构。请注意,它没有 5 的键(5 是键 4 处的值)。
  • 将所有内容编辑为答案。
猜你喜欢
  • 1970-01-01
  • 2012-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多