# Pairwise iterator

**URL:** <https://discourse.julialang.org/t/pairwise-iterator/63927>\
**Category:** General Usage\
**Tags:** iterators\
**Created:** [July 2, 2021, 8:24am UTC](https://discourse.julialang.org/t/pairwise-iterator/63927 "2021-07-02T08:24:02Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![owiecc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/owiecc/32/8894_2.png) [@owiecc](https://discourse.julialang.org/u/owiecc)\
**Post date:** [July 2, 2021, 8:24am UTC](https://discourse.julialang.org/t/pairwise-iterator/63927/1 "2021-07-02T08:24:03Z")

</div>

Imagine you have a vector `[1,2,3,4]` and would like to have easily access adjacent elements:

`(1,2)`  
`(2,3)`  
`(3,4)`

I used to do it with a `for` loop and then just access the `i`-th and `i+1`-th element while looping over `1` to `length()-1`. This seems rather ugly so I made a pairwise iterator

```julia
pairwise(x) = zip(x, last(Iterators.peel(x)))

```

then with

```julia
for (x,y) in pairwise("abcd")
    @show x*y
end

```

you get

```julia
x * y = "ab"
x * y = "bc"
x * y = "cd"

```

Am I reinventing the wheel? Is there anything better?

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [July 2, 2021, 8:50am UTC](https://discourse.julialang.org/t/pairwise-iterator/63927/2 "2021-07-02T08:50:25Z")

</div>

Would this work?

```julia
pair2(x,i) = (x[i], x[i+1])

```

Use broadcasting to spit out the complete set:

```julia
pair2.(Ref(x),1:length(x)-1)

```

---

<div class="post-metadata">

**Author:** ![owiecc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/owiecc/32/8894_2.png) [@owiecc](https://discourse.julialang.org/u/owiecc)\
**Post date:** [July 2, 2021, 9:22am UTC](https://discourse.julialang.org/t/pairwise-iterator/63927/3 "2021-07-02T09:22:58Z")

</div>

> [@rafael.guerra](#):
>
> `1:length(x)-1`

That would not work with e.g. OffsetArrays.jl. It will also not work with stuff like dictionaries that are not indexable. That is why I said I don’t like the `i`-th element solutions.

---

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [July 2, 2021, 9:27am UTC](https://discourse.julialang.org/t/pairwise-iterator/63927/4 "2021-07-02T09:27:47Z")

</div>

From [Introduction · IterTools](https://juliacollections.github.io/IterTools.jl/latest/#partition(xs,-n,-%5Bstep%5D)-1)

```julia
using IterTools

for i in partition(1:9, 2, 1)
    @show i
end

# i = (1, 2)
# i = (2, 3)
# i = (3, 4)
# i = (4, 5)
# i = (5, 6)
# i = (6, 7)
# i = (7, 8)
# i = (8, 9)

d = Dict(:a => 1, :b => 2, :c => 3)

for i in partition(d, 2, 1)
    @show i
end

# i = (:a => 1, :b => 2)
# i = (:b => 2, :c => 3)

```

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [July 2, 2021, 9:28am UTC](https://discourse.julialang.org/t/pairwise-iterator/63927/5 "2021-07-02T09:28:53Z")

</div>

@owiecc, sorry for not having read you well.

---

<div class="post-metadata">

**Author:** ![braydenware](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/braydenware/32/2612_2.png) [@braydenware](https://discourse.julialang.org/u/braydenware)\
**Post date:** [December 8, 2021, 5:43pm UTC](https://discourse.julialang.org/t/pairwise-iterator/63927/6 "2021-12-08T17:43:28Z")

</div>

I discovered today that

> pairwise(xs) = IterTools.partition(xs, 2, 1)

works correctly on iterators that can only be consumed once – such as eachline(“somefile”) – while the above solution

> pairwise(xs) = zip(xs, last(Iterators.peel(xs)))

and the solution I had in my own code

> pairwise(xs) = zip(xs, Iterators.drop(xs, 1))

both produce the wrong result. Thanks for pointing it out!
