【发布时间】:2013-03-05 21:58:40
【问题描述】:
Clojure 是否提供任何内置方法来查找给定序列中子序列的位置?
【问题讨论】:
Clojure 是否提供任何内置方法来查找给定序列中子序列的位置?
【问题讨论】:
Clojure 提供了一种内置方式,方便Java Interop。
(java.util.Collections/indexOfSubList '(a b c 5 6 :foo g h) '(5 6 :foo))
;=> 3
【讨论】:
java.util.List 是seq 的超类,并且java 方法位于java.util.Lists 对上。因此,您可以在惰性序列上使用它(注意不要评估无限序列)(java.util.Collections/indexOfSubList (range 10) (range 3 7)) ;=> 3、向量、排序映射等。
序列是抽象的,而不是具体的。可以通过序列抽象使用的某些实体有一种方法可以找到子序列的位置(例如字符串和 Java 集合),但序列通常不会,因为底层实体不必有索引.
但是,您可以做的是创建元素标识和索引函数的并列。看看map-indexed。
这是一个简单的实现,它将懒惰地找到序列中(所有)子序列的位置。只需使用 first 或取 1 只找到一个:
(defn find-pos
[sq sub]
(->>
(partition (count sub) 1 sq)
(map-indexed vector)
(filter #(= (second %) sub))
(map first)))
=> (find-pos [:a :b \c 5 6 :foo \g :h]
[\c 5 6 :foo])
(2)
=> (find-pos "the quick brown fox"
(seq "quick"))
(4)
请注意,基于索引的算法通常不会在函数式语言中执行。除非有充分的理由需要在最终结果中使用索引,否则过度使用索引查找会被视为代码异味。
【讨论】: