Массивы Ruby и неинкрементные индексы - PullRequest
0 голосов
/ 24 апреля 2011

У меня есть массив в ruby, и я устанавливаю индекс для id объекта, как показано ниже.

Мой первый вопрос:

Этот код работает:

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

но когда я делаю:

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

он говорит:

неопределенный метод [] для nil :: NilClass

Я попытался поставить100 или 1000 вместо i, чтобы убедиться, что это не «индекс вне диапазона», но это сработало, я попытался преобразовать id в int, используя to_i, хотя это уже должно быть int, но это все жене работаетЯ не понимаю.

Мой второй вопрос:

Если я заставляю идентификаторы работать, говорит ли я, что Array.new(@objects.size) становится бесполезным?

Я не являюсьиспользуя индексы от 0 до размера, но идентификаторы, так что же происходит?Это инициализация индексов от 0...size до nil или это просто создание пространства для максимум x объектов?

РЕДАКТИРОВАТЬ:

Так что мне сказали, что лучше использовать Hashдля этого, и я согласен, но у меня все еще, кажется, есть та же самая ошибка в той же самой ситуации (только измененный Array.new(@objects.size) на Hash.new)

Ответы [ 4 ]

1 голос
/ 24 апреля 2011
  1. @array = @objects.map { |obj| obj.value }
  2. Можно, но вам не нужно указывать размер при создании массива. В любом случае, попробуйте использовать функциональные возможности Ruby (map, select, inject) вместо императивных циклов, подобных C.
1 голос
/ 24 апреля 2011

Вы пытаетесь использовать массив как хеш. Попробуйте это:

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

Посмотрите документы Array и Hash .

1 голос
/ 24 апреля 2011

Это не то, как массивы работают в Ruby.Однако вы можете использовать хеш для этого и искать их, используя метод, который вы хотите:

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

Теперь вы можете сделать:

@lookup_hash[@some_object.id]

И он вернет значение этого объектакак вы его сохранили.

Дополнительная информация

Вы также можете переписать свой цикл следующим образом, так как вам больше не нужен индекс:

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

Немного более читабельно, на мой взгляд.

0 голосов
/ 24 апреля 2011

Вы можете использовать map , чтобы сделать это по-русски:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...