Reputation: 1357
I am trying to understand what is a semantically right way to use map
. As map
can behave the same way as each
, you could modify the array any way you like. But I've been told by my colleague that after map
is applied, array should have
the same order and the same size.
For example, that would mean using the map to return an updated array won't be the right way to use map
:
array = [1,2,3,4]
array.map{|num| num unless num == 2 || num == 4}.compact
I've been using map
and other Enumerator
methods for ages and never thought about this too much. Would appreciate advice from experienced Ruby Developers.
Upvotes: 2
Views: 88
Reputation: 160551
Meditate on this:
array = [1,2,3,4]
array.map{|num| num unless num == 2 || num == 4} # => [1, nil, 3, nil]
.compact # => [1, 3]
The intermediate value is an array of the same size, however it contains undesirable values, forcing the use of compact
. The fallout of this is CPU time is wasted generating the nil values, then deleting them. In addition, memory is being wasted generating another array that is the same size when it shouldn't be. Imagine the CPU and memory cost in a loop that is processing thousands of elements in an array.
Instead, using the right tool cleans up the code and avoids wasting CPU or memory:
array.reject { |num| num == 2 || num == 4 } # => [1, 3]
I've been using map and other Enumerator methods for ages and never thought about this too much.
I'd recommend thinking about it. It's the little things like this that can make or break code or a system, and everything we do when programming needs to be done deliberately, avoiding all negative side-effects we can foresee.
Upvotes: 4
Reputation: 9497
In Computer Science, map
according to Wikipedia:
In many programming languages,
map
is the name of a higher-order function that applies a given function to each element of a list, returning a list of results in the same order
This statement implies the returned value of map
should be of the same length (because we're applying the function to each element). And the returned-elements are to be in the same order. So when you use map
, this is what the reader expects.
map
arr.map {|i| arr.pop } #=> [3, 2]
This clearly betrays the intention of map
since we have a different number of elements returned and they are not even in the original order of application. So don't use map
like this. See "How to use ruby's value_at to get subhashes in a hash" and subsequent comments for further clarification and thanks to @meager for originally pointing this out to me.
Upvotes: 4