开发者

Ruby arrays and non-incremental indexes

I have an array in ruby, and I am setting the index to id of object like below.

My first question is:

This code works:

@array = Array.new(@objects.size)
for i in 0...@objects.size
  @array[i] = @objects[i].value
end

but when I do:

 @array[@objects[i].id] = @objects[i].value

it says:

undefined method [] for nil::NilClass

I tried putting 100 or 1000 instead of i to make sure it's not about "index out of range", but those worked, I tried converting 开发者_运维问答id to int by using to_i even though it should already be an int, but it still doesn't work. I don't get it.

My second question is:

If I get to make the ids work, does saying Array.new(@objects.size) become usless?

I am not using indexes 0 to size but IDs, so what is happening? Is it initializing indexes 0...size to nil or is it just creating a space for up to x objects?

EDIT:

So I've been told it is better to use Hash for this, and I agree, But I still seem to have the same error in the same situation (just changed Array.new(@objects.size)toHash.new)


Thats not how Arrays work in Ruby. You can however use a hash to do this, and look them up using the method you want:

@lookup_hash = Hash.new
for i in 0...@objects.size
  @lookup_hash[@objects[i].id] = @objects[i].value
end

Now you can do:

@lookup_hash[@some_object.id]

And it will return that object's value as you have stored it.

Additional Info

You could also rewrite your loop like this, since you dont need the index anymore:

@lookup_hash = Hash.new
@objects.each do |obj|
  @lookup_hash[obj.id] = obj.value
end

A little bit more readable in my opinion.


Your're trying to use an array like a hash. Try this:

Hash[@objects.map{|o| [o.id, o.value] }]

Take a look at the Array and Hash documentations.


  1. @array = @objects.map { |obj| obj.value }
  2. You can, but you don't need to specify the size when creating an array. Anyway, try to use the functional capabilities of Ruby (map, select, inject) instead of C-like imperative loops.


You could use map to do this in a rubyish way:

@array = @objects.map { |o| o.value }

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜