# Iterators, collections, arrays

**URL:** https://discourse.julialang.org/t/iterators-collections-arrays/4871
**Category:** General Usage
**Tags:** question
**Created:** [July 15, 2017, 4:22pm UTC](https://discourse.julialang.org/t/iterators-collections-arrays/4871 "2017-07-15T16:22:21Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![Juan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juan/32/7657_2.png) [@Juan](https://discourse.julialang.org/u/Juan)
#### Post date: [July 15, 2017, 4:22pm UTC](https://discourse.julialang.org/t/iterators-collections-arrays/4871/1 "2017-07-15T16:22:21Z")

</div>

Hello.

I’ve being reading a little bit some basic Julia tutorials and I have a doubt:

Could anyone explain the difference between Iterators, collections and arrays, please.  
I’m coming from R and there aren’t iterators or collections there, I don’t understand why we need it.

For example in R you can just do

> 1:10

but in Julia you need to to

> collect(1:1:10)

Or you need to use

> collect(permutations(1:4))

instead of just

> permutations(1:4)

---

<div class="post-metadata">

### Author: ![joshday](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joshday/32/368_2.png) [@joshday](https://discourse.julialang.org/u/joshday)
#### Post date: [July 15, 2017, 4:54pm UTC](https://discourse.julialang.org/t/iterators-collections-arrays/4871/2 "2017-07-15T16:54:51Z")

</div>

It’s not necessary to store every single number in order to iterate over a range of equally spaced numbers, so Julia takes advantage of this. Rather than create a temporary vector, Julia uses a data type that uses less memory and does the same thing.

```julia
julia> typeof(1:10)
UnitRange{Int64}

julia> typeof(collect(1:10))
Array{Int64,1}

julia> sizeof(1:100)
16

julia> sizeof(collect(1:100))
800

```

---

<div class="post-metadata">

### Author: ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)
#### Post date: [July 15, 2017, 5:14pm UTC](https://discourse.julialang.org/t/iterators-collections-arrays/4871/3 "2017-07-15T17:14:41Z")

</div>

My understanding is that iterators simply allow you to loop over objects. In R, you loop over an integer index. In Julia, it is also possible to loop over objects. For example, you can iterate over an array of arrays:

```julia
 data = [rand(2,2) for i in 1:10]
 for d in data
    println(d)
 end

```

Using iterators like this is certainly not necessary, but it can be convenient and easier to read. You can also iterate over the object and index with enumerate() or multiple objects concurrently with zip().

> [@Juan](#):
>
> collect(1:1:10)

By the way, if you are simply initializing an array, you can use

> [1:10;]

as a shorthand.

---

<div class="post-metadata">

### Author: ![Juan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juan/32/7657_2.png) [@Juan](https://discourse.julialang.org/u/Juan)
#### Post date: [July 15, 2017, 5:57pm UTC](https://discourse.julialang.org/t/iterators-collections-arrays/4871/4 "2017-07-15T17:57:53Z")

</div>

What about

> permutations(1:4)

And what other things can you do directly with the iterators without transforming them with colllect()?

---

<div class="post-metadata">

### Author: ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)
#### Post date: [July 15, 2017, 7:39pm UTC](https://discourse.julialang.org/t/iterators-collections-arrays/4871/5 "2017-07-15T19:39:56Z")

</div>

Many of the core mathematical operations still work with the unit range type. For example,

```julia
m = 1:4
m*m'

4×4 Array{Int64,2}:
 1 2 3 4
 2 4 6 8
 3 6 9 12
 4 8 12 16

```

So for certain operations, you do not need to use collect(). Multiple dispatch handles that for you. There might be other uses that I am not aware of.

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [July 15, 2017, 7:46pm UTC](https://discourse.julialang.org/t/iterators-collections-arrays/4871/6 "2017-07-15T19:46:04Z")

</div>

Just assume that you never need to collect. In some small number of cases you may want to anyway, but probably less than 1% of the time.

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [July 15, 2017, 9:13pm UTC](https://discourse.julialang.org/t/iterators-collections-arrays/4871/7 "2017-07-15T21:13:05Z")

</div>

> [@Christopher\_Fisher](#):
>
> My understanding is that iterators simply allow you to loop over objects.

Just to be clear, a range like `1:10` in Julia is not just an iterator (= any type you can loop over, i.e. any type with `start`, `next`, `done`, and usually `eltype` and `length`), it is a subtype of `AbstractVector` (and has all usual array methods like `getindex` and `ndims`), so you can mostly treat it as a drop-in replacement for a read-only array.

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [July 15, 2017, 9:42pm UTC](https://discourse.julialang.org/t/iterators-collections-arrays/4871/8 "2017-07-15T21:42:44Z")

</div>

> [@stevengj](#):
>
> so you can mostly treat it as a drop-in replacement for a read-only array.

That’s the key. Since it doesn’t allocate memory, usually it will work in circumstances where it’s read-only. `1:4` never makes an array, but `A=1:4; A[1]` still works. But since there is no array in memory to actually write to, `A[1] = 4` fails without `collect`ing to a real array. So if you pass it into algorithms which use the array but don’t write into it, 99% of the time you’re fine. The other 1% is someone too stictly typing their dispatches (i.e. a bug to report).

---

<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: [July 16, 2017, 8:08am UTC](https://discourse.julialang.org/t/iterators-collections-arrays/4871/9 "2017-07-16T08:08:21Z")

</div>

> [@Juan](#):
>
> reading a little bit some basic Julia tutorials

It is possible that some of those are outdated — Julia evolves very rapidly. Read the [manual](https://docs.julialang.org/en/stable/).

Iteration (traversal of a collection) is implemented using generic functions in Julia. This means that for each type, you can specify [how](https://docs.julialang.org/en/stable/manual/interfaces/#man-interface-iteration-1) it is traversed. This has various advantages: some stuctures have a layout which favors a certain kind of traversal, and in some cases, the values can be generated very cheaply on demand, as for `1:10`. This is a big advantage compared to R, where `1:10000` means that you actually allocate that vector.

In principle, every function that can expects an iterable object should be able to deal with types that implement the interface. `collect` is a workaround for when it is not the case: eg `collect(1:10)` converts to a vector `[1,2,3,4,5,6,7,8,9,10]`. As a user, design your code so that it works with all iterables (simply not restricting the type will be fine in most cases). If you encounter restrictive behavior in a library, report an issue.
