Как получить ссылку на хеш, оперируемый в таких методах, как reject? - PullRequest
0 голосов
/ 11 февраля 2012

Мне интересно, есть ли более чистый подход к этому:

hash = { 1 => 10, 2 => 33, 3 => 5, 4 => 33 }
hash.reject { |key, value| value != hash.values.max }.keys

Я хочу быть в состоянии сделать это:

{ 1 => 10, 2 => 33, 3 => 5, 4 => 33 }.reject { |key, value| value != HASH_BEING_OPERATED_ON.values.max }.keys

Но блок в отклонении нуждается вссылка на хеш, с которым работает reject.Возможно ли это?

Ответы [ 3 ]

3 голосов
/ 11 февраля 2012

Кроме того, возможно ли это или нет, вы не должны делать это, потому что это неэффективно. Вы пересчитываете максимальное значение в каждой итерации. Почему бы просто не вычислить максимум до итерации?

max = hash.values.max
hash.select{|_, value| value == max}.keys
1 голос
/ 11 февраля 2012

Как правило, это невозможно, потому что это не очень хорошая практика. Изменение коллекции в середине цикла может привести к неожиданным результатам.

Скажем Array#each_with_index установите переменную self в блоке на массив, по которому вы выполняли итерацию. Вместо получения массива [1, 2, 3, 4, 5, 4, 8] этот цикл теперь становится бесконечным:

[1, 2, 3, 4, 5].each_with_index do |number, index|
  self << number * 2 if number % 2 == 0
end

Конечно, ничто не мешает вам делать это в любом случае с локальными переменными, но, явно предоставив доступ к массиву в цикле, Ruby сделает подобные ошибки намного более распространенными.

Я не предполагаю, что это то, что вы делаете в вашем примере. Я просто констатирую то, что я представлял себе как дизайн языка.

1 голос
/ 11 февраля 2012

Это выглядит немного странно, но это одна строка, которая работает, не будучи неэффективной:

hash.group_by{|_,v|v}.sort.last.last.transpose.first

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