2017-01-29 4 views
2

Как я могу перебирать элементы коллекции в Clojure, чтобы я мог получить доступ к предыдущим, текущим и следующим значениям на каждой итерации.Как перебирать коллекцию и иметь доступ к предыдущим, текущим и следующим значениям на каждой итерации?

Со следующим вектором:

[1 2 3 4] 

Я хотел бы иметь доступ к следующим значениям в каждой итерации:

[nil 1 2] 
[1 2 3] 
[2 3 4] 
[3 4 nil] 
+0

рекурсивная функция, которая принимает несколько аргументов и передать их в качестве аргументов повторялись? Похоже, я не понял ваш вопрос. –

+0

@ DavidBern вы можете поместить образец кода? – eliocs

+1

Его так учит читать вопросы и ответы в сообществе clojure. Я чувствую себя настолько глупо в сравнении. Решением, которое я имел в виду, было следующее: (loop [prev nil, [current & next] [0, 1, 2, 3, 4, 5, 6, 7]] (если (nil? Next) current (do (println next) (recur current next)))) При взгляде на ответ, данный Эрвином, я поражен тем, как я ушел, чтобы узнать :) –

ответ

5

Один из способов сделать это с помощью concat тин nil до и после сбор и partition Использование элементов 3 с шагом в размере 1.

(def c [1 2 3 4]) 
(def your-fn println) ;; to print some output later 
(map your-fn 
    (map vec (partition 3 1 (concat [nil] c [nil])))) 

(Вы можете удалить map vec часть, если она также хорошо, если элементы в LazySeq вместо вектора.)

который печатает:

[ноль 1 2]
[1 2 3]
[2 3 4]
[3 4 ноль]

+0

Не знал, что функция 'partition' действительно полезна! – eliocs

3

Вот loop/recur реализация с использованием destructoring.

(let [s [1 2 3 4]] 
    (loop [[prev & [cur nxt :as more]] (cons nil s) 
     result []] 
    (if (seq more) 
     (recur more (conj result [prev cur nxt])) 
     result))) 
+0

Очень сложно понять это решение. – eliocs

+2

@eliocs После того, как вы используете внутреннее деструктурирование, это довольно интуитивно понятно, тем не менее, если вам нужно универсальное многоразовое решение, я бы рекомендовал более функциональную конструкцию, такую ​​как два других ответа. –

+0

Наконец-то моя голова вокруг очень крутая – eliocs

3

Я бы рекомендовал технику разделения, но еще одна хитрость заключается в map над ступенчатыми экземплярами одной и той же последовательности:

(let [s [1 2 3 4]] 
    (map vector (cons nil s) 
       s 
       (concat (drop 1 s) [nil]))) 

-> ([nil 1 2] [1 2 3] [2 3 4] [3 4 nil]) 

 Смежные вопросы

  • Нет связанных вопросов^_^