开发者

Looping and creating an array in Ruby

Trying to port some old PHP code to Ruby and missing some key info on creating arrays in Ruby.

The PHP code:

foreach ($results as $r) {
    $array[$r['column']][] = $r
}

Is this the simplest way to do it in Ruby? Do I have to initialize the second array?

@array = []
result.each do |r|
  @array[r.cron_column] = []
  @array[r.开发者_开发知识库cron_column] << r
end

I figure this is a simple syntax issue, but my Googling has turned up empty. Thanks for your help!


You are indexing into an empty array, so that will always return nil. nil does not define the << operator, so you get an error. You need to initialize the value at array[index] if you want to use the << operator.

I am assuming you want an array of arrays, so you can use this instead which will initialize the value at items[index] to an empty array if it is nil before pushing the value onto it

items = []
array.each do |r|
  (items[r.column] ||= []) << r
end

The only change here is that, if items[r.column] returns nil it will be set equal to an empty array, otherwise nothing will be done. If you really just want to set the value at items[index] to r, just use the = operator.


Are you sure you need an array as output? it would appear a hash would be more convenient; moreover, it's way easier to build in your scenario (which is usually a sign you are in the correct path):

# example
results = [
  OpenStruct.new(:x => 1, :cron_column => 0), 
  OpenStruct.new(:x => 2, :cron_column => 1), 
  OpenStruct.new(:x => 3, :cron_column => 1),
] 

@array = results.group_by(&:cron_column)
# {0=>[#<OpenStruct x=1, cron_column=0>], 
#  1=>[#<OpenStruct x=2, cron_column=1>, #<OpenStruct x=3, cron_column=1>]}

If cron_column "has no holes" (that's it, you have values from 0 to N), you can easily create an array with this same idea: results.group_by(&:cron_column).sort.map { |k, v| v } or results.group_by(&:cron_column).sort.map(&:last), as you prefer.


array = results.inject([]) { |m, r| m[r.column] = r; m }

Update: oh, e1[] = e2 adds a new array element in PHP, so tokland is right, in which case:

array = results.inject([]) { |m, r| (m[r.column] ||= []) << r; m }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜