# Check two iterators for equality without collecting

**URL:** <https://discourse.julialang.org/t/check-two-iterators-for-equality-without-collecting/3631>\
**Category:** General Usage\
**Tags:** question\
**Created:** [May 10, 2017, 3:05pm UTC](https://discourse.julialang.org/t/check-two-iterators-for-equality-without-collecting/3631 "2017-05-10T15:05:14Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [May 10, 2017, 3:05pm UTC](https://discourse.julialang.org/t/check-two-iterators-for-equality-without-collecting/3631/1 "2017-05-10T15:05:14Z")

</div>

I am looking for simple syntax that would compare two iterators `itr1`, `itr2` for elementwise equality _without collecting_, and break early if there is a difference. MWE:

```julia
julia> VERSION
v"0.6.0-rc1.0"

julia> all(1:3 .== [1,2,3])
true

julia> all(1:3 .== (i for i in 1:3)) # but I want this to be true
false

```

Note that I know how to implement it, I am looking for simple _syntax_, equivalent to

```julia
function itreq(itr1, itr2)
    for (i1,i2) in zip(itr1, itr2)
        i1 == i2 || return false
    end
    true
end

itreq(1:3, (i for i in 1:3))

```

**EDIT** : I realized I really want something equivalent to `collect(itr1) == collect(itr2)`, but without `collect`. Ie different lengths should also return false, so `all(... .== ...)` is not good.

In case you are wondering, this is just out of curiosity, the code in question has no performance impact. I am validating that a list of Cartesian indexes are really contiguous and in the right order, with a function not unlike

```julia
function combined_size(indexes)
    siz = reduce(max, indexes)
    ran = CartesianRange(siz)
    # FIXME inelegant collect below
    @argcheck collect(indexes) == collect(ran) "Non-contiguous indexes."
    siz
end

```

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [May 10, 2017, 3:45pm UTC](https://discourse.julialang.org/t/check-two-iterators-for-equality-without-collecting/3631/2 "2017-05-10T15:45:01Z")

</div>

We should probably have methods for `all` and `any` that work like `map`, taking a predicate which takes as many arguments as you pass iterables. Could you open a feature request issue?

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [May 10, 2017, 5:29pm UTC](https://discourse.julialang.org/t/check-two-iterators-for-equality-without-collecting/3631/3 "2017-05-10T17:29:20Z")

</div>

I thought about it and I am not sure it is a good idea. Something like

```julia
all(f, itr...) = all(tup->f(tup...), zip(itr...))

```

would work, apart from the fact that it would conflict with `all(f::Function, A::AbstractArray, region)` when used with two iterables, however

```julia
all(==, 1:3, (i for i in 1:4))

```

would be `true`, which is not necessarily what I want. One would need to test for one sequence consumed earlier than the other, but `mapreduce` would just finish silently.

---

<div class="post-metadata">

**Author:** ![andyferris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/andyferris/32/235_2.png) [@andyferris](https://discourse.julialang.org/u/andyferris)\
**Post date:** [May 11, 2017, 9:47am UTC](https://discourse.julialang.org/t/check-two-iterators-for-equality-without-collecting/3631/4 "2017-05-11T09:47:33Z")

</div>

Typically map etc error out if the sizes aren’t compatible, and so should an iteration version of mapreduce.

---

<div class="post-metadata">

**Author:** ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)\
**Post date:** [May 11, 2017, 1:36pm UTC](https://discourse.julialang.org/t/check-two-iterators-for-equality-without-collecting/3631/5 "2017-05-11T13:36:20Z")

</div>

How about defining:  
`iterequal(iter,iters...) = all(t->length(t)==length(iter),iters) && all(all(t->t==x[1],x[2]) for x in zip(iter,zip(iters...)))`

which uses `all` which is short-circuiting on boolean predicates.

In this examples:  
`julia> iterequal(1:3,1:3) true`

and  
`julia> iterequal(1:3,1:4) false`

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [May 12, 2017, 3:52pm UTC](https://discourse.julialang.org/t/check-two-iterators-for-equality-without-collecting/3631/6 "2017-05-12T15:52:39Z")

</div>

Only `zip` ignores length differences, stopping as soon as the first argument stops, and there’s an open issue somewhere with a lot of support for changing that (including from me).

---

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [May 12, 2017, 3:57pm UTC](https://discourse.julialang.org/t/check-two-iterators-for-equality-without-collecting/3631/7 "2017-05-12T15:57:40Z")

</div>

[https://github.com/JuliaLang/julia/issues/20499](https://github.com/JuliaLang/julia/issues/20499)
