List comprehension in Ruby

2019-01-10 04:57发布

To do the equivalent of Python list comprehensions, I'm doing the following:

some_array.select{|x| x % 2 == 0 }.collect{|x| x * 3}

Is there a better way to do this...perhaps with one method call?

14条回答
劫难
2楼-- · 2019-01-10 05:51

There seems to be some confusion amongst Ruby programmers in this thread concerning what list comprehension is. Every single response assumes some preexisting array to transform. But list comprehension's power lies in an array created on the fly with the following syntax:

squares = [x**2 for x in range(10)]

The following would be an analog in Ruby (the only adequate answer in this thread, AFAIC):

a = Array.new(4).map{rand(2**49..2**50)} 

In the above case, I'm creating an array of random integers, but the block could contain anything. But this would be a Ruby list comprehension.

查看更多
别忘想泡老子
3楼-- · 2019-01-10 05:55

I discussed this topic with Rein Henrichs, who tells me that the best performing solution is

map { ... }.compact`

This makes good sense because it avoids building intermediate Arrays as with the immutable usage of Enumerable#inject, and it avoids growing the Array, which causes allocation. It's as general as any of the others unless your collection can contain nil elements.

I haven't compared this with

select {...}.map{...}

It's possible that Ruby's C implementation of Enumerable#select is very good also.

查看更多
登录 后发表回答