# Help fo working with Iters

**URL:** https://discourse.julialang.org/t/help-fo-working-with-iters/29727
**Category:** New to Julia
**Created:** [October 10, 2019, 1:19pm UTC](https://discourse.julialang.org/t/help-fo-working-with-iters/29727 "2019-10-10T13:19:00Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![hasanOryx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hasanoryx/32/5373_2.png) [@hasanOryx](https://discourse.julialang.org/u/hasanOryx)
#### Post date: [October 10, 2019, 1:19pm UTC](https://discourse.julialang.org/t/help-fo-working-with-iters/29727/1 "2019-10-10T13:19:00Z")

</div>

I’ve the below `Python` code:

```python
def initial_trend(series, slen):
    sum = 0.0
    for i in range(slen):
        sum += float(series[i+slen] - series[i]) / slen
    return sum / slen

```

That is converted to the below `Rust` code:

```rust
fn initial_trend(series: &[i32], slen: usize) -> f32 {
    series[..slen].iter().zip(&series[slen..])
        .map(|(&a, &b)| (b as f32 - a as f32) / slen as f32).sum::<f32>() / slen as f32
}

```

Or can be re-written as:

```rust
fn initial_trend(series: &[i32], slen: usize) -> f32 {
    let x = series[..slen].iter().zip(&series[slen..]);
    let y = x.map(|(&a, &b)| (b as f32 - a as f32) / slen as f32);
    let z = y.sum::<f32>();
    z / slen as f32
}

```

for the input, with `slen = 12`:

```julia
series = [30,21,29,31,40,48,53,47,37,39,31,29,17,9,20,24,27,35,41,38,
          27,31,27,26,21,13,21,18,33,35,40,36,22,24,21,20,17,14,17,19,
          26,29,40,31,20,24,18,26,17,9,17,21,28,32,46,33,23,28,22,27,
          18,8,17,21,31,34,44,38,31,30,26,32];

```

I’ve the below output in `Rust` code above

```bash
x = Zip { a: Iter([30, 21, 29, 31, 40, 48, 53, 47, 37, 39, 31, 29]), b: Iter([17, 9, 20, 24, 27, 35, 41, 38, 27, 31, 27, 26, 21, 13, 21, 18, 33, 35, 40, 36, 22, 24, 21, 20, 17, 14, 17, 19, 26, 29, 40, 31, 20, 24, 18, 26, 17, 9, 17, 21, 28, 32, 46, 33, 23, 28, 22, 27, 18, 8, 17, 21, 31, 34, 44, 38, 31, 30, 26, 32]), index: 0, len: 12 }

y = Map { iter: Zip { a: Iter([30, 21, 29, 31, 40, 48, 53, 47, 37, 39, 31, 29]), b: Iter([17, 9, 20, 24, 27, 35, 41, 38, 27, 31, 27, 26, 21, 13, 21, 18, 33, 35, 40, 36, 22, 24, 21, 20, 17, 14, 17, 19, 26, 29, 40, 31, 20, 24, 18, 26, 17, 9, 17, 21, 28, 32, 46, 33, 23, 28, 22, 27, 18, 8, 17, 21, 31, 34, 44, 38, 31, 30, 26, 32]), index: 0, len: 12 } }

z = -9.416667

w = -0.78472227

```

I want to write the equivalent `Julia` code, so I wrote the below:

```julia
function initial_trend(series, slen)
    x = zip(series[1:slen], series[slen+1:end])
    y = map((a, b) -> (b - a) / 2, x)
    z = sum(y) / slen
end

```

With this `x` looks to be correct as it generates:

```bash
Base.Iterators.Zip{Tuple{Array{Int64,1},Array{Int64,1}}}(([30, 21, 29, 31, 40, 48, 53, 47, 37, 39, 31, 29], [29, 17, 9, 20, 24, 27, 35, 41, 38, 27, 31, 27, 26, 21, 13, 21, 18, 33, 35, 40, 36, 22, 24, 21, 20, 17, 14, 17, 19, 26, 29, 40, 31, 20, 24, 18, 26, 17, 9, 17, 21, 28, 32, 46, 33, 23, 28, 22, 27, 18, 8, 17, 21, 31, 34, 44, 38, 31, 30, 26, 32]))

```

But `y` is wrong, not working, it gave me:

```bash
MethodError: no method matching (::getfield(Main, Symbol("##17#18")))(::Tuple{Int64,Int64})
Closest candidates are:
  #17(::Any, !Matched::Any) at In[38]:1

```

it looks I do not understand working with tuples in arrays with map!  
And not sure if I’ve to d something before `x`, and if there is a way to make all of them in single line like the one in `Rust`

---

<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: [October 10, 2019, 1:33pm UTC](https://discourse.julialang.org/t/help-fo-working-with-iters/29727/2 "2019-10-10T13:33:00Z")

</div>

You are probably looking for

```julia
map(((a, b),) -> ...)

```

(note extra `()`s), but I don’t see the point of `zip`ing and then splatting. Can’t you just do

```julia
y = map((a, b) -> b - a / 2, series[1:slen], series[slen:end])

```

? Or even

```julia
(series[slen:end] .- series[1:slen]) ./ 2

```

Incidentally, it may be better to just ask for what you want to achieve in Julia, instead of pasting code from other languages. Julia has different idioms, and not everyone is fluent in other computer languages.

Also, you may just want to read through the Julia manual first to learn about these things, otherwise your experience with Julia might just end up being quite frustrating.

---

<div class="post-metadata">

### Author: ![hasanOryx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hasanoryx/32/5373_2.png) [@hasanOryx](https://discourse.julialang.org/u/hasanOryx)
#### Post date: [October 10, 2019, 1:35pm UTC](https://discourse.julialang.org/t/help-fo-working-with-iters/29727/3 "2019-10-10T13:35:21Z")

</div>

> [@Tamas\_Papp](#):
>
> (series[slen:end] .- series[1:slen]) ./ 2

for this I got:

```bash
DimensionMismatch("arrays could not be broadcast to a common size")

```

---

<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: [October 10, 2019, 1:39pm UTC](https://discourse.julialang.org/t/help-fo-working-with-iters/29727/4 "2019-10-10T13:39:33Z")

</div>

Just think about it for a sec. Eg imagine that `series` has 10 elements and `slen` is 2.

---

<div class="post-metadata">

### Author: ![hasanOryx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hasanoryx/32/5373_2.png) [@hasanOryx](https://discourse.julialang.org/u/hasanOryx)
#### Post date: [October 10, 2019, 1:40pm UTC](https://discourse.julialang.org/t/help-fo-working-with-iters/29727/5 "2019-10-10T13:40:05Z")

</div>

> [@Tamas\_Papp](#):
>
> y = map((a, b) → b - a / 2, series[1:slen], series[slen:end])

for this also,I got the same:

```julia
y = map((a, b) -> (b - a) / 2, series[1:12], series[12+1:end])

```

```bash
DimensionMismatch("dimensions must match")

```

---

<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: [October 10, 2019, 1:42pm UTC](https://discourse.julialang.org/t/help-fo-working-with-iters/29727/6 "2019-10-10T13:42:23Z")

</div>

Of course, it’s the same problem.

---

<div class="post-metadata">

### Author: ![klaff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/klaff/32/7637_2.png) [@klaff](https://discourse.julialang.org/u/klaff)
#### Post date: [October 10, 2019, 1:46pm UTC](https://discourse.julialang.org/t/help-fo-working-with-iters/29727/7 "2019-10-10T13:46:31Z")

</div>

Maybe:

```julia
function initial_trend(series, slen)
   sum = 0.0
   for i in 1:slen
       sum += series[i+slen]-series[i]
   end
   return sum/slen
end

```

I worked from the python and removed what I suspect is a redundant `/slen` (it is being done both in the loop and outside the loop).

P.S. I’m assuming that `series` is a vector of floats.

---

<div class="post-metadata">

### Author: ![hasanOryx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hasanoryx/32/5373_2.png) [@hasanOryx](https://discourse.julialang.org/u/hasanOryx)
#### Post date: [October 10, 2019, 1:53pm UTC](https://discourse.julialang.org/t/help-fo-working-with-iters/29727/8 "2019-10-10T13:53:49Z")

</div>

Thanks, actually the other `slen` is required, not extra

```julia
     sum += (series[i+slen]-series[i]) / slen

```

Your code with returning the `slen` gave me the correct output, so now how can I covert this `Julia` code to `functional` format using `Iter`

---

<div class="post-metadata">

### Author: ![hasanOryx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hasanoryx/32/5373_2.png) [@hasanOryx](https://discourse.julialang.org/u/hasanOryx)
#### Post date: [October 10, 2019, 2:28pm UTC](https://discourse.julialang.org/t/help-fo-working-with-iters/29727/9 "2019-10-10T14:28:04Z")

</div>

> [@Tamas\_Papp](#):
>
> imagine that `series` has 10 elements and `slen` is 2.

So, how can we enforce it to work based on the shortest array, so for 10 and 2, it will take only the first 2 elements from the array of 10

---

<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: [October 10, 2019, 2:41pm UTC](https://discourse.julialang.org/t/help-fo-working-with-iters/29727/10 "2019-10-10T14:41:48Z")

</div>

> [@hasanOryx](#):
>
> it will take only the first 2 elements from the array of 10

~~`zip` does that. did you read my very first reply?~~ nope it does not work that way. I would just calculate indexes to match in length, like @dmolina suggests, and maybe use `@view`.

---

<div class="post-metadata">

### Author: ![dmolina](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dmolina/32/5246_2.png) [@dmolina](https://discourse.julialang.org/u/dmolina)
#### Post date: [October 10, 2019, 2:42pm UTC](https://discourse.julialang.org/t/help-fo-working-with-iters/29727/11 "2019-10-10T14:42:39Z")

</div>

In that case, I would suggest:

```julia
y = map((a, b) -> (b - a) / 2, series[1:slen-1], series[slen+1:2*slen])

```

Be careful with indexes, julia series[1:n] includes n index, while Python does not.

Edit: Sorry, it was missing a parenthesis.

---

<div class="post-metadata">

### Author: ![hasanOryx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hasanoryx/32/5373_2.png) [@hasanOryx](https://discourse.julialang.org/u/hasanOryx)
#### Post date: [October 10, 2019, 2:48pm UTC](https://discourse.julialang.org/t/help-fo-working-with-iters/29727/12 "2019-10-10T14:48:42Z")

</div>

> [@dmolina](#):
>
> y = map((a, b) → (b - a) / 2, series[1:slen], series[slen+1:slen])

I got:

```bash
DimensionMismatch("dimensions must match")

```

Iter `b` is bigger than iter `a` so it fails, how can I ask it to take the first `x` elements in iter `b` where `x` is the `length(a)`

---

<div class="post-metadata">

### Author: ![dmolina](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dmolina/32/5246_2.png) [@dmolina](https://discourse.julialang.org/u/dmolina)
#### Post date: [October 10, 2019, 2:58pm UTC](https://discourse.julialang.org/t/help-fo-working-with-iters/29727/13 "2019-10-10T14:58:13Z")

</div>

My code was working inspired in Python, which does not explore to the end, so until 2\*slen. Please, do not submit versions if other language if it is not right.

If you want to avoid problem you should use zip as @Tamas_Papp suggested:

```julia
function initial_trend(series, slen)
   sum = 0.0

   for (a, b) in zip(series[1:slen], series[slen+1:end])
        sum += (b-a)/slen
   end
   return sum/slen
end

```

This code should give the same than Rust version.

---

<div class="post-metadata">

### Author: ![hasanOryx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hasanoryx/32/5373_2.png) [@hasanOryx](https://discourse.julialang.org/u/hasanOryx)
#### Post date: [October 10, 2019, 3:10pm UTC](https://discourse.julialang.org/t/help-fo-working-with-iters/29727/14 "2019-10-10T15:10:40Z")

</div>

> [@dmolina](#):
>
> for (a, b) in zip(series[1:slen], series[slen+1:end]) sum += (b-a)/slen end

The `zip(series[1:slen], series[slen+1:end])` is fine, and your code gave correct result,  
Can I replace:

```julia
for (a,b) in .. 
     sum+=(b-a)/slen
end

```

with `map()` function?

---

<div class="post-metadata">

### Author: ![dmolina](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dmolina/32/5246_2.png) [@dmolina](https://discourse.julialang.org/u/dmolina)
#### Post date: [October 10, 2019, 3:20pm UTC](https://discourse.julialang.org/t/help-fo-working-with-iters/29727/15 "2019-10-10T15:20:37Z")

</div>

I do not think so, zips stop when one of them finish before the other one, but for some reason this check is only done in a for loop, not inside a map or the collect function.

---

<div class="post-metadata">

### Author: ![klaff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/klaff/32/7637_2.png) [@klaff](https://discourse.julialang.org/u/klaff)
#### Post date: [October 10, 2019, 3:38pm UTC](https://discourse.julialang.org/t/help-fo-working-with-iters/29727/16 "2019-10-10T15:38:07Z")

</div>

Two comments then:

1. If you need to divide by `slen` twice, shouldn’t that still happen outside the loop? (i.e. `return sum/slen^2` gives me the correct answer).
2. I don’t understand what you are trying to do or need. I frankly get lost with all the zips and maps when the simple for loop is perfectly readable and produces the correct answer.

---

<div class="post-metadata">

### Author: ![hasanOryx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hasanoryx/32/5373_2.png) [@hasanOryx](https://discourse.julialang.org/u/hasanOryx)
#### Post date: [October 10, 2019, 3:52pm UTC](https://discourse.julialang.org/t/help-fo-working-with-iters/29727/17 "2019-10-10T15:52:46Z")

</div>

Thanks to all the inputs and feedbacks given, I solved it as:

```julia
initial_trend(series, slen) = sum(
    map(i -> (last(i) - first(i)) / slen, 
        zip(series[1:slen], series[slen+1:2*slen])
        )
    ) / slen

```

I was having 2 issues:

1. As @dmolina [mentioed](https://discourse.julialang.org/t/help-fo-working-with-iters/29727/15) zipping is not stopping in mapping when one of the `iters` finish before the other one

2. Tuple in mapping is not handled as `map((a,b) -> ... , x)`, it is handled as `map(i -> ... , x)`, then can be handled as `first(i)` and so on.

---

<div class="post-metadata">

### Author: ![hasanOryx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hasanoryx/32/5373_2.png) [@hasanOryx](https://discourse.julialang.org/u/hasanOryx)
#### Post date: [October 10, 2019, 3:58pm UTC](https://discourse.julialang.org/t/help-fo-working-with-iters/29727/18 "2019-10-10T15:58:15Z")

</div>

> [@klaff](#):
>
> If you need to divide by `slen` twice, shouldn’t that still happen outside the loop?

You are correct, but I’m trying to keep the coding formula matching with the mathematical formulas

> [@klaff](#):
>
> when the simple for loop is perfectly readable and produces the correct answer

I would like to do it the functional programming way. thanks a lot for your feedbacks

---

<div class="post-metadata">

### Author: ![klaff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/klaff/32/7637_2.png) [@klaff](https://discourse.julialang.org/u/klaff)
#### Post date: [October 10, 2019, 5:20pm UTC](https://discourse.julialang.org/t/help-fo-working-with-iters/29727/19 "2019-10-10T17:20:27Z")

</div>

I used @btime from BenchmarkTools to compare the loop version to the sum/map/zip version. I’m not sure if you care about speed or if this is an academic exercise but the simple loop runs 5x faster with less memory usage.

```julia
julia> @btime initial_trend(series, 12)
  131.302 ns (7 allocations: 624 bytes)
-0.7847222222222222

julia> @btime initial_trend_for_loop(series, 12)
  24.727 ns (1 allocation: 16 bytes)
-0.7847222222222222

```

---

<div class="post-metadata">

### Author: ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)
#### Post date: [October 11, 2019, 6:02am UTC](https://discourse.julialang.org/t/help-fo-working-with-iters/29727/20 "2019-10-11T06:02:29Z")

</div>

If you want a “functional” approach, you can also do

```julia
initial_trend(series, slen) =
    mapreduce(+, zip(series[1:slen], series[slen+1:2*slen])) do (a, b)
        (b - a) / slen
    end / slen

```

If you care performance a bit then,

```julia
function initial_trend(series, slen)
    x = @view series[1:slen]
    y = @view series[slen+1:2*slen]
    n = min(length(x), length(y))
    mapreduce(+, (@view x[1:n]), (@view y[1:n])) do a, b
        (b - a) / slen
    end / slen
end

```

The latter in principle should be almost as fast as the raw loop and has better accuracy.

[Next page](https://discourse.julialang.org/t/help-fo-working-with-iters/29727.md?page=2)
