2014-01-27 10 views
6

Die clojure Dokumentation von split-at besagt, dass es eine Sammlung von Elementen nimmt und gibt eine vector von zwei lists mit jeweils Elemente größer oder kleiner ist als ein gegebener Index:Split ein Vektor in den Vektor der Vektoren in clojure anstelle von Vektor von Listen

(split-at 2 [1 2 3 4 5]) 
[(1 2) (3 4 5)] 

Was ich will, ist dies:

(split-at' 2 [1 2 3 4 5]) 
[[1 2] [3 4 5]] 

Dies ist eine Sammlung in zwei Sammlungen geschnitten ist, die die Reihenfolge der Elemente halten (wie Vektoren), vorzugsweise ohne Leistungseinbußen.

Was ist der übliche Weg dies zu tun und gibt es leistungsoptimierte Möglichkeiten?

Antwort

11

Wenn Sie ausschließlich mit Vektoren arbeiten, wäre eine Option, zu verwenden.

(defn split-at' [idx v] 
    [(subvec v 0 idx) (subvec v idx)]) 

(split-at' 2 [1 2 3 4 5]) 
;; => [[1 2] [3 4 5]] 

In Bezug auf die Leistung betrifft, die Dokumentationen zu subvec Zustand:

Diese Operation O (1) und sehr schnell ist, wie der resultierende Vektor Aktien-Struktur mit dem Original und keine Trimmen ist erledigt.

+0

Benötigt Befestigung für den leeren Vektor. Was funktioniert mit 'split-at' – ClojureMostly

+0

@ClojureMostly Es scheint gut zu funktionieren für den leeren Vektor, so weit ich sagen kann:' (= [[] []] (split-at '0 [])) ' –

+0

'split-at' arbeitet auch mit' (split-at 2 []) ' – ClojureMostly

2

Warum nicht die Kernfunktion mit "Vec" Funktion erweitern?

(defn split-at 
    "Returns a vector of [(take n coll) (drop n coll)]" 
    {:added "1.0" 
    :static true} 
    [n coll] 
    [(take n coll) (drop n coll)]) 

Wir vec auf jedes Element des Vektors Ergebnis

(defn split-at-vec 
    [n coll] 
    [(vec (take n coll)) (vec (drop n coll))]) 

releated hinzufügen können, um "Leistungseinbußen" Ich denke, dass, wenn Sie Ihre Transformation:

auf Split-at Definition So basiert Lazy Seqs zugunsten von Vektor dann verlieren Sie die faule Leistung.

Verwandte Themen