Ruby: создание хэша из строки и двух значений массива одновременно - PullRequest
3 голосов
/ 01 декабря 2011

Я пытаюсь создать хеш с:

hash = {}

strings = ["one", "two", "three"]

array = [1, 2, 3, 4, 5, 6]

так что я получаю:

hash = { "one" => [1, 2] ,
         "two" => [3, 4] ,
         "three" => [5, 6] }

Я пробовал:

strings.each do |string|
  array.each_slice(2) do |numbers|
    hash[string] = [numbers[0], numbers[1]]
  end
end

Но это дает:

hash = { "one" => [5,6] , "two" => [5,6], "three" => [5,6] }

Я знаю, почему это происходит (вложенные циклы), но я не знаю, как добиться того, что я ищу.

Ответы [ 3 ]

14 голосов
/ 01 декабря 2011

Если вы хотите однострочник:

hash = Hash[strings.zip(array.each_slice(2))]

Например:

>> strings = ["one", "two", "three"]
>> array = [1, 2, 3, 4, 5, 6]
>> hash = Hash[strings.zip(array.each_slice(2))]
=> {"one"=>[1, 2], "two"=>[3, 4], "three"=>[5, 6]}
1 голос
/ 01 декабря 2011
hash = {}
strings.each { |string| hash[string] = array.slice!(0..1) }

Это решение, использующее методы и приемы, которые вам знакомы. Это не решение «одного лайнера», но если вы новичок, это может быть более понятно для вас. Первый ответ очень элегантный.

0 голосов
/ 01 декабря 2011

Как говорит Му, лучше всего выбрать метод Zip:

Преобразует любые аргументы в массивы, затем объединяет элементы self с соответствующими элементами из каждого аргумента. Это генерирует последовательность массивов n-элементов self.size, где n - это еще одно число аргументов. Если размер какого-либо аргумента меньше, чем enumObj.size, предоставляются значения nil. Если указан блок, он вызывается для каждого выходного массива, в противном случае возвращается массив массивов.

...