Reputation: 2762
Let's say I have an array of stuff that I want to perform all sorts of wacky operations on. For example:
my_array = [
{ name: 'Lyra', age: 12 },
{ name: 'Harry', age: 11 },
{ name: 'Kestrel', age: 13},
]
I want to filter out anyone under the age of 12, change all names to symbols, and then sort them by age (say).
This can be achieved with:
new_array = my_array.
select { |person| person[:age] > 11 }.
map { |person| person.merge(name: person[:name].to_sym) }.
sort_by { |person| person[:age] }
So that's all dandy. But what if I have arbitrarily complex logic I need to do my selecting/mapping/sorting/etc.?
Standard practice says that multi-line blocks with braces are to be avoided (and some linters even outright forbid it). Yet, the alternative is to start chaining do..end
blocks, which looks even ickier:
new_array = my_array.
select do |person|
# Do something complex
end.
map do |person|
# More complex stuff
end.
sort_by do |person|
# Yet more complex stuff
end
Does the Ruby community have any advice on best practice for chaining this sort of thing? For example, is it nicer to define a Proc
(or similar), and pass that into the block?
Upvotes: 4
Views: 165
Reputation: 114188
You could create a copy and use destructive methods instead:
new_array = my_array.dup
new_array.select! do |person|
# Do something complex
end
new_array.map! do |person|
# More complex stuff
end
new_array.sort_by! do |person|
# Yet more complex stuff
end
Upvotes: 4