Clojure는 주어진 시퀀스에서 하위 시퀀스의 위치를 찾는 기본 제공 방법을 제공합니까?순서대로 Clojure 하위 시퀀스 위치
5
A
답변
7
Clojure는 쉬운 방법을 제공합니다. Java Interop.
(java.util.Collections/indexOfSubList '(a b c 5 6 :foo g h) '(5 6 :foo))
;=> 3
3
시퀀스는 추상이 아니라 concretion입니다. 시퀀스 추상화를 통해 사용할 수있는 특정 Concretion에는 하위 시퀀스 (예 : 문자열 및 Java 컬렉션)의 위치를 찾는 방법이 있지만 일반적으로 시퀀스는 기본 concretion에 인덱스가 없어야하므로 사용할 수 없습니다 .
그러나 할 수있는 일은 요소 ID와 색인 기능을 결합한 것입니다. map-indexed을보십시오.
다음은 순차적으로 (모든) 하위 시퀀스의 위치를 느리게 찾을 수있는 순진한 구현입니다. 먼저 사용하거나 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)
일반적으로 색인 기반 알고리즘은 기능적 언어에서 수행하지 않아도됩니다. 최종 결과에 색인이 필요한 좋은 이유가 없으면 색인 조회를 풍부하게 사용하면 코드 냄새가 난다.
답장을 보내 주셔서 감사합니다. 이것이 내가 결국 사용할 것이지만, 일반적으로 Java Interop을 '비즈니스'코드에서 명시 적으로 호출하는 것을 피하려고합니다. 좀 더 자세하게 설명 하겠지만. 그럼에도 불구하고 고맙습니다. –
이것이 작동하는 동안 컬렉션이 시퀀스가 아니라는 점에 유의하십시오. – NielsK
@NielsK 철학적 개념을 제쳐두고,'java.util.List'를'seq'의 수퍼 클래스로, java 메소드가'java.util.List' 쌍에 있다고 생각합니다. 이 방법은 게으른 시퀀스에서 사용할 수 있습니다 (무한한 것을 평가하지 않도록주의)'(java.util.Collections/indexOfSubList (range 10) (range 3 7)); => 3', vectors, sorted- 지도 등 –