为什么Clojure核心库不支持索引功能?

时间:2018-07-23 15:09:47

标签: clojure clojure-java-interop

最近,我通常从Clojure编程和函数式编程开始。我注意到,解决了一些基本的编程难题的一件事是,例如,向量没有索引功能。核心功能nth无反。我见过人们自己实现它或使用一些Java替代实现。

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

2 个答案:

答案 0 :(得分:3)

以相反的顺序回答两个问题:

“解决方法” :clojure中的INSERT INTO tblProjects VALUES (DEFAULT, ?, ?, NULL ...) 实现了vector,因此java的工作非常简单(足够优雅,imo)

java.util.List

此外,字符串可以利用(.indexOf [1 2 3] 2) 1

为什么不在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

答案 1 :(得分:1)

一个标准的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对的序列提供给地图,以提供给map-invert)。