2014-01-04 3 views
1

В Python я могу создать тестовый хэш со списком, который я проверю на набор тестов. Как я могу добиться того же в рубине? (Я бегу на рубин 1.9.3)Ruby: Сопоставление хэша

Python:

test = {x: self.investor.annual_return(x) for x in xrange(1, 6)} 

Ruby (попытка):

test = Hash[(1..5).map { |x| [x, @investor.annual_return(x)] }] 
+0

Итак, вы хотите отобразить с 1 по 6 на 'self.investor.annual_return (1)' через 'self.investor.annual_return (6)' as '{1 => self.investor.annual_return (1), 2 = > self.investor.annual_return (2) ... '? – Beartech

+0

annual_return вытаскивает значение массива, которое вычисляет процентное значение компаундирования.В этом случае я собираю хеш для создания этого без фактического ввода: 1 => 10720.00, 2 => 11491.84, 3 => 12319.25, 4 => 13206.24, 5 => 14517.09 – theGrayFox

+0

Тогда @ennuikiller - это ответьте, что хотите. Мне пришлось искать список, но похоже, что определение в Википедии содержит «предикатную статью», которую я не вижу в вашем примере. Как и в «итерации с 1 по 5, и сделайте число ключом и возвратом функции этого числа значение, НО только если некоторое предложение предиката также истинно», их пример python: «S = [2 * x для x в диапазон (101), если x ** 2> 3] ', а их пример Ruby:' (1..100). select {| x | x ** 2> 3} .collect {| x | 2 * x} ' – Beartech

ответ

1

Вы часто видите:

test = (1..5).reduce({}) {|h, x| h[x] = @investor.annual_return(x); h} 

, но (с Ruby 1.9) многие предпочитают Enumerable#each_with_object:

test = (1..5).each_with_object({}) {|x, h| h[x] = @investor.annual_return(x)} 

частично потому, что нет необходимости возвращать объект h итерату или, как есть, с Enumerable#reduce (aka inject).

+1

Боже, это гораздо более читаемо. Я попробовал это, уменьшив первый ход, но не смог правильно получить синтаксис. Я просто путаюсь с обратной сделкой с '' '| x, h | ч [х] .''' – theGrayFox

2

Вы хотите что-то вроде:

test = {} 
(1..5).map { |i| test[i] = @investor.annual_return(i) } 
+0

Я с ним ласкался, сейчас я придумал подходящее решение. Это немного сложно, потому что Ruby не имеет такой же настройки, как понимание Python's Dict. Что вы думаете о моей реализации? – theGrayFox

+1

Не используйте для этого 'map', используйте' each'. В то время как 'map' будет перебирать диапазон, как' each', он попытается вернуть массив всех сгенерированных значений, назначенных 'test [i]', поскольку он итерации, что отнимает процессорное время. 'each' - простой итератор и не будет возвращать массив, чтобы он был более эффективным. –

0

Если я правильно понимаю, что вы пытаетесь g, вы можете попробовать следующее:

{}.tap { |x| (1..5).each do |y| x[y] = @investor.annual_return(i) end } 
2

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

Начиная с:

class Investor 
    def annual_return(i) 
    i * i 
    end 
end 

investor = Investor.new 

В Ruby 1.9+, это будет работать:

test = Hash[ (1..5).map { |x| [x, investor.annual_return(x)] } ] 
test # => {1=>1, 2=>4, 3=>9, 4=>16, 5=>25} 

Однако до 1,9, Hash не преобразовать массив массивов, содержащий пары ключ/значение , поэтому нам нужно было немного поучаствовать, и flatten вложенные элементы в единый массив, затем «взорвать» те элементы для хэша:

test = Hash[ *(1..5).map { |x| [x, investor.annual_return(x)] }.flatten ] 
test # => {1=>1, 2=>4, 3=>9, 4=>16, 5=>25} 

Результат тот же, это просто меньше хлопот в эти дни.

И, просто чтобы показать, что делает рубин, как мы строим Хэш таким образом:

(1..5).map { |x| [x, investor.annual_return(x)] } 
# => [[1, 1], [2, 4], [3, 9], [4, 16], [5, 25]] 

(1..5).map { |x| [x, investor.annual_return(x)] }.flatten 
# => [1, 1, 2, 4, 3, 9, 4, 16, 5, 25] 
+0

Вижу, я ценю объяснение! – theGrayFox

0

Вы можете сделать это легко с:

(1..5).map { |x| [x, @investor.annual_return(x)] }.to_h 

(Doc: Array#to_h)

Hash[*array] используется для построения хэш из плоского массива ([key1, value1, key2, value2, keyN, valueN]), в то время как Array#to_h используется для построения хэш из массива пар ключ-значение ([ [key1, value1], [key2, value2], [keyN, valueN] ]).

Смежные вопросы