gpt4 book ai didi

clojure - 从Clojure中的序列中获取元素

转载 作者:行者123 更新时间:2023-12-04 09:36:04 27 4
gpt4 key购买 nike

我知道Clojure中的列表和向量在大多数情况下几乎可以互换使用。这是一个让我惊讶的简单案例

(nth [2 4] 0) ;=> 2
(nth '(2 4) 0) ;=> 2
(get [2 4] 0) ;=> 2
(get '(2 4) 0) ;=> nil -- wtf???
get的文档讨论映射键,但是它可以与向量或集合配合使用。 nth的文档甚至提到了 get,仅在边缘情况下谈论它们的差异。

面对这种奇怪行为的现实情况是,我加载了yaml文件。这导致了 map 和列表的嵌套结构。我想使用 get-in访问一个元素。
(def form (parse-yaml some-yaml-file))
(def best-friend (get-in form [:friends 0 :first-name]))

这是行不通的,因为 get-in在内部使用了 get。所以我有一个理论上和实践上的问题:
  • get的这种行为是否被认为是正确的和预期的?如果是这样,请说明原因。
  • 如何访问这种结构的 map 和列表中的嵌套元素?
  • 最佳答案

    get的行为是正确的和预期的。 get适用于“键控”数据结构,其中值映射到键。这包括将索引映射到value1和set2的向量。

    列表不提供对元素的随机访问;它们应线性移动。由于支持的访问模式是如此不同,因此列表和向量绝对不打算互换使用,并且核心Clojure集合库不竭力支持这种用法。 (nth是一个函数的奇怪示例,该函数同时执行低性能的常数或对数时间查找和线性遍历; Clojure地区的怪兽)。

    当然,“修改”还有其他区别(在持久数据结构意义上:创建修改后的副本),例如conj的工作方式以及vector的assoc的可用性(如脚注中所述;替换列表中的元素会涉及到此为止重建整个前缀)。

    如果您想对数据使用类似矢量的访问模式,则应将其放在矢量中。列表可以使用vec转换为向量(线性时间)。如果您要处理的序列化格式不明确,是否应该为某些数据返回列表或向量,并且解析器不接受告诉其应使用哪种格式的选项,则您可能必须自己进行一些后处理( clojure.walk可能有用,特别是prewalkpostwalk函数;这是假定仅涉及基本Clojure数据类型)。

    1实际上,向量更是如此:它们是关联的,因此您可以将它们与assoc一起使用((assoc [0 1 2] 0 :foo)返回[:foo 1 2];仅支持不超过(count the-vector)的索引,以便assoc将向量中已经存在且紧随结尾的索引)。

    2为了便于讨论,可以考虑使用集合将其成员映射到自己。这实际上在Clojure中是正确的,在某种意义上,用作函数的集合在应用到它时会返回成员本身(对于非成员,则返回nil),并且在某种意义上,这就是实现的内幕。

    关于clojure - 从Clojure中的序列中获取元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16623788/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com