In clojure how to map over overlapping pairs?

喜你入骨 提交于 2019-12-19 11:46:49

问题


Say I have the sequence:

[1 2 3 4 5]

And I want to map over them in the pairs:

[(1, 2), (2, 3), (3, 4), (4, 5)]

I have tried:

(map f (partition 2 [1 2 3 4]))

But this results in the sequence of pairs:

[(1, 2), (3, 4)]

How can I get the desired functionality?


回答1:


By default partiton returns non-overlapping partitions, but you can supply a step argument to provide the offset at which partitions are created:

clojure.core/partition
([n coll] [n step coll] [n step pad coll])
  Returns a lazy sequence of lists of n items each, at offsets step
  apart. If step is not supplied, defaults to n, i.e. the partitions
  do not overlap. If a pad collection is supplied, use its elements as
  necessary to complete last partition upto n items. In case there are
  not enough padding elements, return a partition with less than n items.

This will do what you want:

(partition 2 1 [1 2 3 4 5 6 7 8]))
; #=> ((1 2) (2 3) (3 4) (4 5) (5 6) (6 7) (7 8))



回答2:


An alternative would be map both with the list you have and the rest of the list. E.g.:

(user=> (let [l [1 2 3 4 5]] (map list l (rest l)))
((1 2) (2 3) (3 4) (4 5))



回答3:


I would do it as follows

; first generate data 
; (that is if you really are talking about all the ints)
(map (juxt identity inc) [1 2 3 4 5])
=> ([1 2] [2 3] [3 4] [4 5] [5 6])

; inline example
(map (comp 
       (fn [[a b]] (println a b)) ; this would be your f
       (juxt identity inc)) [1 2 3 4 5])

; using your function f
(map (comp 
       f
       (juxt identity inc)) [1 2 3 4 5])



回答4:


This also works independent of the order of numbers in your vector:

(let [a [5 4 3 2 1] b (rest a)] (map vector a b))

will yield:

([5 4] [4 3] [3 2] [2 1])


来源:https://stackoverflow.com/questions/32435877/in-clojure-how-to-map-over-overlapping-pairs

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!