1

I have a loop inside which I am appending the result of the loop to an array. The code is like this

urls = []
series_id = [100,200,300,400]
series_id.each do |id|
  result_urls += iterate_id_and_get_urls(id)
end

def iterate_id_and_get_urls(id)
  #do something with id and maps it and returns its url which would result in an array
  #return that url array
end

But iterate_id_and_get_urls(id) can also return nil sometimes which would result nil to be appended in result_urls. How can I avoid that. I am looking for something like the below

result_urls += iterate_id_and_get_urls(id) unless nil?
3
  • result_urls += iterate_id_and_get_urls(id) unless iterate_id_and_get_urls(id) = nil Commented Nov 20, 2014 at 12:51
  • You can do result_urls.compact at the end which will remove all nil values Commented Nov 20, 2014 at 12:53
  • @HetalKhunti I can do like this result_urls += iterate_id_and_get_urls(id) unless iterate_id_and_get_urls(id) = nil. But that would make call to iterate_id_and_get_urls(id) twice, if I am not wrong.. Commented Nov 20, 2014 at 13:12

3 Answers 3

3

How about using flat_map:

result_urls = series_id.flat_map { |id| iterate_id_and_get_urls(id) }.compact

or even:

result_urls = series_id.flat_map { |id| iterate_id_and_get_urls(id) || [] }
Sign up to request clarification or add additional context in comments.

1 Comment

When I heard about flat_map, I thought to myself, this is like flatten, cool but not much use for it. You found a good usecase here, congrats.
2

You can try something like

series_id.each do |id|
  if value = iterate_id_and_get_urls(id)
    result_urls += value.compact
  end
end

So nil url's will not get added to result_urls

Compact : Returns a copy of self with all nil elements removed.

7 Comments

use unless instead of if !
And also, is the conditional necessary at all if you use #compact?
#compact removes nil and returns empty array. In ruby [] is also evaluated as true. so #empty? returns true or false. based on that value gets appended to result_urls
Yes, but I suspect that if you drop it, the code will work anyway =)
Simple statement result_urls += value.compact will work, to be completely clear.
|
1
series_id.map( &method( :iterate_id_and_get_urls ) ).compact.reduce( [], :+ ).compact

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.