2014-07-23 4 views
1

Я новичок в clojure, и некоторые из них, как я нахожу простые манипуляции с массивами, которые легко выполнять в python, слишком сложно сделать в clojure. Например, что такое идиоматический способ сделать это в clojure?Идиоматический способ перебрать массив в Clojure

for i = 1 to len(arr)-1: 
    sum[i] = arr[i-1] + i 
+0

Clojure имеет специализированные функции для работы с родными массивами Java, о которых я сомневаюсь, о чем вы спрашиваете здесь. Пожалуйста, подумайте о том, чтобы перефразировать этот вопрос, если вы действительно говорите о более общем списке или операции последовательности. – Alex

+0

Попробуйте взглянуть на https://blog.safaribooksonline.com/2013/07/24/sequence-abstractions-in-clojure/ или одну из многих отличных книг Clojure. – Alex

+1

Оператор Python 'for' недействителен (устаревший?): Try' for i in range (1, len (arr)): ... ' – Thumbnail

ответ

5

Clojure имеет хороший набор функций sequence manipulation, которые часто полезны для этих общих задач. этот пример будет (map-indexed + arr)

user> (def arr [1 2 38 2 3 9 4 2]) 
#'user/arr 
user> (map-indexed + arr) 
(1 3 40 5 7 14 10 9) 

хотя это только из-за конкретный пример, который вы выбрали. Более общий ответ - использовать map, mapv, reduce, или reductions или for для такого рода вещей. Например:

user> (for [i (range 0 (count arr))] (+ i (arr i))) 
(1 3 40 5 7 14 10 9) 
+0

да, вы правы. Я исправлю это. –

+0

Пробовал ли вы код Python? Как указано, я не могу его скомпилировать (на Python 2.7.6 - текущий для Ubuntu). Как только синтаксис исправлен, он дает результаты, отличные от ваших (см. [Здесь] (http://stackoverflow.com/a/24929270/1562315)). И подумайте, что код Python не приписывает значение 'sum [0]', тогда как вы это делаете. – Thumbnail

0

Для начала давайте сделаем @ArthurUlfeldt's example в Python.

arr = [1, 2, 38, 2, 3, 9, 4, 2] 

и, скажем

sum = [None, None, None, None, None, None, None, None] 

Выполнение (исправленное/обновляется?) Python

for i in range(1, len(arr)): 
    sum[i] = arr[i-1] + i 

... дает нам

sum 
;[None, 2, 4, 41, 6, 8, 15, 11] 

Чтобы преобразовать это в Clojure , вытесните индекс Python на 1, давая

for i in range(len(arr) - 1): 
    sum[i+1] = arr[i] + (i+1) 

Теперь мы можем построить правую как

(map + (butlast arr) (iterate inc 1)) 
;(2 4 41 6 8 15 11) 

... который мы преобразовать в вектор, начиная с индекса 1:

(vec (cons nil (map + (butlast arr) (iterate inc 1)))) 
;[nil 2 4 41 6 8 15 11] 

Вероятно, мы хотим свяжите это значение в a let:

(let [sum (vec (cons nil (map + (butlast arr) (iterate inc 1))))] 
    #_(... use `sum` here)) 
Смежные вопросы