🎉 Exercism Research is now launched. Help Exercism, help science and have some fun at research.exercism.io 🎉 # jaeyson's solution

## to Accumulate in the Elixir Track

Published at Mar 19 2021 · 0 comments
Instructions
Test suite
Solution

Implement the `accumulate` operation, which, given a collection and an operation to perform on each element of the collection, returns a new collection containing the result of applying that operation to each element of the input collection.

Given the collection of numbers:

• 1, 2, 3, 4, 5

And the operation:

• square a number (`x => x * x`)

Your code should be able to produce the collection of squares:

• 1, 4, 9, 16, 25

Check out the test suite to see the expected function signature.

## Restrictions

Keep your hands off that collect/map/fmap/whatchamacallit functionality provided by your standard library! Solve this one yourself using other basic tools instead.

## Running tests

Execute the tests with:

``````\$ mix test
``````

### Pending tests

In the test suites, all but the first test have been skipped.

Once you get a test passing, you can unskip the next one by commenting out the relevant `@tag :pending` with a `#` symbol.

For example:

``````# @tag :pending
test "shouting" do
assert Bob.hey("WATCH OUT!") == "Whoa, chill out!"
end
``````

Or, you can enable all the tests by commenting out the `ExUnit.configure` line in the test suite.

``````# ExUnit.configure exclude: :pending, trace: true
``````

If you're stuck on something, it may help to look at some of the available resources out there where answers might be found.

## Source

Conversation with James Edward Gray II https://twitter.com/jeg2

## Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

### accumulate_test.exs

``````defmodule AccumulateTest do
use ExUnit.Case

test "accumulate empty list" do
assert Accumulate.accumulate([], fn n -> n * n end) == []
end

@tag :pending
test "accumulate square numbers" do
assert Accumulate.accumulate([1, 2, 3], fn n -> n * n end) == [1, 4, 9]
end

@tag :pending
test "accumulate upcased strings" do
fun = fn w -> String.upcase(w) end
assert Accumulate.accumulate(["hello", "world"], fun) == ["HELLO", "WORLD"]
end

@tag :pending
test "accumulate reversed strings" do
fun = fn w -> String.reverse(w) end
words = ~w(the quick brown fox etc)
expected = ["eht", "kciuq", "nworb", "xof", "cte"]
assert Accumulate.accumulate(words, fun) == expected
end

@tag :pending
test "nested accumulate" do
chars = ~w(a b c)
nums = ~w(1 2 3)
fun = fn c -> Accumulate.accumulate(nums, &(c <> &1)) end
expected = [["a1", "a2", "a3"], ["b1", "b2", "b3"], ["c1", "c2", "c3"]]
assert Accumulate.accumulate(chars, fun) == expected
end
end``````

### test_helper.exs

``````ExUnit.start()
ExUnit.configure(exclude: :pending, trace: true)``````

### lib/accumulate.ex

``````defmodule Accumulate do
@doc """
Given a list and a function, apply the function to each list item and
replace it with the function's return value.

Returns a list.

## Examples

iex> Accumulate.accumulate([], fn(x) -> x * 2 end)
[]

iex> Accumulate.accumulate([1, 2, 3], fn(x) -> x * 2 end)
[2, 4, 6]

"""

@spec accumulate(list, (any -> any)) :: list
def accumulate([], _fun), do: []

def accumulate([h | t] = _list, fun) do
[fun.(h) | accumulate(t, fun)]
end
end``````

### test/accumulate_test.exs

``````defmodule AccumulateTest do
use ExUnit.Case

test "accumulate empty list" do
assert Accumulate.accumulate([], fn n -> n * n end) == []
end

# @tag :pending
test "accumulate square numbers" do
assert Accumulate.accumulate([1, 2, 3], fn n -> n * n end) == [1, 4, 9]
end

# @tag :pending
test "accumulate upcased strings" do
fun = fn w -> String.upcase(w) end
assert Accumulate.accumulate(["hello", "world"], fun) == ["HELLO", "WORLD"]
end

# @tag :pending
test "accumulate reversed strings" do
fun = fn w -> String.reverse(w) end
words = ~w(the quick brown fox etc)
expected = ["eht", "kciuq", "nworb", "xof", "cte"]
assert Accumulate.accumulate(words, fun) == expected
end

# @tag :pending
test "nested accumulate" do
chars = ~w(a b c)
nums = ~w(1 2 3)
fun = fn c -> Accumulate.accumulate(nums, &(c <> &1)) end
expected = [["a1", "a2", "a3"], ["b1", "b2", "b3"], ["c1", "c2", "c3"]]
assert Accumulate.accumulate(chars, fun) == expected
end
end``````