Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Map an array modifying only elements matching a certain condition

In Ruby, what is the most expressive way to map an array in such a way that certain elements are modified and the others left untouched?

This is a straight-forward way to do it:

old_a = ["a", "b", "c"]                         # ["a", "b", "c"]
new_a = old_a.map { |x| (x=="b" ? x+"!" : x) }  # ["a", "b!", "c"]

Omitting the "leave-alone" case of course if not enough:

new_a = old_a.map { |x| x+"!" if x=="b" }       # [nil, "b!", nil]

What I would like is something like this:

new_a = old_a.map_modifying_only_elements_where (Proc.new {|x| x == "b"}) 
        do |y|
          y + "!"
        end
# ["a", "b!", "c"]

Is there some nice way to do this in Ruby (or maybe Rails has some kind of convenience method that I haven't found yet)?


Thanks everybody for replying. While you collectively convinced me that it's best to just use map with the ternary operator, some of you posted very interesting answers!

like image 841
Yang Meyer Avatar asked Mar 05 '09 11:03

Yang Meyer


People also ask

How do you add a condition to an array map?

To use a condition inside map() in React:Call the map() method on an array. Use a ternary operator to check if the condition is truthy. The operator returns the value to the left of the colon if the condition is truthy, otherwise the value to the right is returned.

What's the difference between map and reduce?

Generally "map" means converting a series of inputs to an equal length series of outputs while "reduce" means converting a series of inputs into a smaller number of outputs. What people mean by "map-reduce" is usually construed to mean "transform, possibly in parallel, combine serially".

What is map in Javascript with example?

Definition and Usage. map() creates a new array from calling a function for every array element. map() calls a function once for each element in an array. map() does not execute the function for empty elements.

Can you have an array of maps?

C++ allows us a facility to create an array of maps. An array of maps is an array in which each element is a map on its own.


2 Answers

Because arrays are pointers, this also works:

a = ["hello", "to", "you", "dude"]
a.select {|i| i.length <= 3 }.each {|i| i << "!" }

puts a.inspect
# => ["hello", "to!", "you!", "dude"]

In the loop, make sure you use a method that alters the object rather than creating a new object. E.g. upcase! compared to upcase.

The exact procedure depends on what exactly you are trying to achieve. It's hard to nail a definite answer with foo-bar examples.

like image 184
August Lilleaas Avatar answered Oct 22 '22 03:10

August Lilleaas


old_a.map! { |a| a == "b" ? a + "!" : a }

gives

=> ["a", "b!", "c"]

map! modifies the receiver in place, so old_a is now that returned array.

like image 43
Ryan Bigg Avatar answered Oct 22 '22 03:10

Ryan Bigg