Skip to content

Latest commit

 

History

History
105 lines (84 loc) · 1.81 KB

map_reduce.md

File metadata and controls

105 lines (84 loc) · 1.81 KB

Map

Two big modules:

ages  = [35, 34, 6, 5, 1, 1]
add_10 = fn (age) -> age + 10 end
Enum.map ages, add_10

Results in...

[55, 54, 26, 25, 21, 21]

The Pipeline alternative might look like this:

[2, 4, 6] |>
  Enum.map(&IO.inspect(&1)) |>
  Enum.map(&(&1 * 10)) |>
  Enum.map(&IO.inspect(&1))
ages  = [35, 34, 6, 5, 1, 1]
add_20 = fn (age) -> age + 20 end
Stream.map ages, add_20

Results in...

Stream.Lazy[enum: [35, 34, 6, 5, 1, 1],
  funs: [#Function<32.133702391 in Stream.map/2>], accs: [], after: [],
  last: nil]

Streams are composable and don't execute until asked to provide a value.

stream = [2, 4, 6] |>
  Stream.map(&IO.inspect(&1)) |>
  Stream.map(&(&1 *2)) |>
  Stream.map(&IO.inspect(&1))

Enum.to_list stream

Results in...

2
4
4
8
6
12
[4, 8, 12]

The [2, 4, 6] showcases the ability to compose a stream as a series of transformations and evalute the operation as a single iteration. If you look closely, the order of operations changed from the Enum example because instead of iterating the list three separate times as the first example, the second transformation happens with a single iteration of the set.

next = fn (x) ->
  x + 1
end
sleep = fn(x) -> 
  :timer.sleep 1000
  x
end
tap = fn(x) ->
  IO.puts "Hey #{x}"
end


Stream.iterate(0,next) |> Stream.each(tap) |> Stream.each(sleep) |> Enum.take(10)

Hey 0
Hey 1
Hey 2
Hey 3
Hey 4
Hey 5
Hey 6
Hey 7
Hey 8
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Reduce

Enum.reduce 1..10, 0, &(&1 + &2)
Enum.map_reduce([1, 2, 3], 0, fn(x, acc) -> { x * 2, 1 + acc } end)

Results in...

{[2,4,6], 3}