a common idiom

M

Michel Demazure

I often have to write something like

some_enumerator.collect ... # or collect.with_index ...
....
next if ...
...
end.reject(&:nil?)

Is there a better way to do a "collect_unless_nil", avoiding the double
processing ?
_md
 
M

Michael Fellinger

I often have to write something like

some_enumerator.collect ... # or collect.with_index ...
....
next if ...
...
end.reject(&:nil?)

Is there a better way to do a "collect_unless_nil", avoiding the double
processing ?
_md

For one, you can use #compact instead of #reject.
The way I'd do it is:

results = []
some.each do |value|
results << value.operation if value.condition?
end

And then you could also use inject, which is a bit harder to grasp at
a glance and a bit more wordy, but some people believe you should
avoid variables outside of blocks at all costs... even if you end up
assigning the results to one.

some.inject [] do |results, value|
next results unless value.condition?
results << value.operation
end

Also, at least since 1.9, you can use `some.each_with_index` or
`some.to_enum.with_index.inject`.
 
R

Ryan Davis

I often have to write something like

some_enumerator.collect ... # or collect.with_index ...
....
next if ...
...
end.reject(&:nil?)

Is there a better way to do a "collect_unless_nil", avoiding the double
processing ?

compact:

result = collection.map { |x|
next if x.hinkey?
}.compact

that will be a LOT faster than your second pass with reject/nil?.
 
M

Michel Demazure

Michael Fellinger wrote in post #971622:
Yes ! I knew there was a method, but forgot the name, browsed thru
Flanagan-Matz, and did not find it.
results = []
some.each do |value|
results << value.operation if value.condition?
end

Yes, returning results, but I try to avoid this extra variable. I
dislike (question of taste) the pattern
def ...
res = []
...
res <<
...
res
end

Another way is using tap

Array.new.tap do |res|
...
end

A bit snob, no ?
 
M

Michel Demazure

Ryan Davis wrote in post #971625:
}.compact

that will be a LOT faster than your second pass with reject/nil?.
Yes, that's what I was looking for (could not remember/guess the name).
Thks
 
G

Guten

[Note: parts of this message were removed to make it a legal post.]

enumerator.each_with_object [] do |value, memo|
memo << value if value.nil?
end


Michael Fellinger wrote in post #971622:
Yes ! I knew there was a method, but forgot the name, browsed thru
Flanagan-Matz, and did not find it.
results = []
some.each do |value|
results << value.operation if value.condition?
end

Yes, returning results, but I try to avoid this extra variable. I
dislike (question of taste) the pattern
def ...
res = []
...
res <<
...
res
end

Another way is using tap

Array.new.tap do |res|
...
end

A bit snob, no ?
 
G

Guten

[Note: parts of this message were removed to make it a legal post.]

enumerator.each_with_object [] do |value, memo|
memo << value unless value.nil?
end


enumerator.each_with_object [] do |value, memo|
memo << value if value.nil?
end



Michael Fellinger wrote in post #971622:
Yes ! I knew there was a method, but forgot the name, browsed thru
Flanagan-Matz, and did not find it.
results = []
some.each do |value|
results << value.operation if value.condition?
end

Yes, returning results, but I try to avoid this extra variable. I
dislike (question of taste) the pattern
def ...
res = []
...
res <<
...
res
end

Another way is using tap

Array.new.tap do |res|
...
end

A bit snob, no ?
 
M

Michel Demazure

A benchmark for the five variants
user system total real
[] 3.235000 0.047000 3.282000 ( 3.296875)
tap 3.265000 0.000000 3.265000 ( 3.265625)
compact 3.547000 0.016000 3.563000 ( 3.562500)
reject 5.078000 0.015000 5.093000 ( 5.093750)
memo 9.610000 0.000000 9.610000 ( 9.609375)

_md
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
474,141
Messages
2,570,817
Members
47,364
Latest member
Stevanida

Latest Threads

Top