代码之家  ›  专栏  ›  技术社区  ›  Lurzim Sabahudin

为什么Clojure核心库不支持函数索引?

  •  1
  • Lurzim Sabahudin  · 技术社区  · 6 年前

    最近,我开始学习Clojure编程和一般的函数编程。我注意到的一点是,解决一些基本的编程难题时,没有向量的函数索引,例如,核心函数没有反转。 nth . 我见过人们自己实现或使用一些Java替代实现。

    我的问题不在于是否有解决方法(但如果你知道一个特别优雅的方法,请分享),因为我知道有。我想知道的是:为什么会出现这种情况,例如,为什么Clojure开发人员决定不执行看起来像这样的基本操作。在Clojure中,在向量中进行位置查找是不是不惯用的,理想情况下是以其他方式进行的?怎么用?

    2 回复  |  直到 6 年前
        1
  •  1
  •   Thumbnail    6 年前

    那里 一个标准的clojure函数 问题 要求。

    如果我们看看 the skeleton source ,我们需要做的是反转一个序列,比如…

    (def ranks [2 3 4 5 6 7 8 9 10 :jack :queen :king :ace])
    

    …映射(或其他函数),它为我们提供 每一个 价值观:

    {7 5, :king 11, 4 2, :queen 10, :ace 12, 6 4, 3 1, 2 0, :jack 9, 9 7, 5 3, 10 8, 8 6}
    

    我们可以做到 一劳永逸 .

    几乎做到这一点的标准功能是 clojure.set/map-invert .

    • 但它适用于地图,而不是序列。
    • 但它将它们视为成对的序列。

    因此,将一个向量(或其他序列)转化为一个索引函数的简单函数是…

    (defn indexes-of [v]
      (->> v
           (map-indexed vector)
           (clojure.set/map-invert)))
    

    例如,

       (indexes-of ranks)
    => {7 5, :king 11, 4 2, :queen 10, :ace 12, 6 4, 3 1, 2 0, :jack 9, 9 7, 5 3, 10 8, 8 6}
    

    所以那些说你的观点是错误的人是正确的。 然而,在Clojure内部执行这样的无域计算肯定会更好,不管Clojure如何顺利地与运行在上面的任何VM对接。

    我们需要的是一件斗篷,它能把一个矢量抛到地图上:就像 rseq 将斗篷投射到向量上,使其显示为反转序列。那么我们不需要假设 map-invert 将接受成对的序列。(为了安全起见,我们现在可以输入成对的序列 into 要提供给的地图 地图反转 )

        2
  •  3
  •   Vlad Bokov    6 年前

    按相反顺序回答两个问题:

    “解决方法” 答: vector 在Clojure工具中 java.util.List 所以Java工作简单(足够优雅,IMO)

    (.indexOf [1 2 3] 2)
    1
    

    此外,字符串还可以利用 clojure.string/index-of

    为什么? 不在clojure.core中:这相当于一个问题“为什么对于各种收集类型没有[多态性fn]”,这里回答: https://clojure.org/guides/faq#conj 这里呢 https://gist.github.com/reborg/dc8b0c96c397a56668905e2767fd697f#why-clojure-doesnt-have-a-generic-insert-lookup-append-that-works-the-same-on-all-collections