2016-02-12 2 views
1

Я пытаюсь создать метод, который будет принимать хэш:Преобразование хэш в массив

{"H"=> 1, "e"=> 1, "l"=> 3, "o"=> 2, "W"=> 1, "r"=> 1, "d"=> 1} 

в качестве параметра и возвращает массив его пар ключ-значение, как, например:

arr = [["H", 1], ["e", 1], ..., ["d", 1]] 

у меня есть следующие, но недостатки:

def toCountsArray(counts) 
    arr = [] 
    i = 0 
    counts.each do |key, value| 
    arr[i].push [key, value] 
    i += 1 
    end 
    return arr 
end 

Я не должен использовать метод to_a или какой-либо помощник. Любая помощь или руководство приветствуются.

+2

Обратите внимание, при написании рубина, есть очень сильное соглашение для имен методов, чтобы быть 'underscore_style', а не' mixedCase'. Это немного, но это помогает вашему коду лучше вписаться, избегая программирования с акцентом. – tadman

+0

Я следую стилю кодировки, который предоставил мне мой профессор, но я согласен с вами. @tadman –

+0

Я бы попросил вашего профессора ссылку на руководство по стилю, которая объясняет эти причудливые соглашения, потому что я никогда не видел одного адвоката. Если у них есть некоторые нерегулярные требования, я надеюсь, что они где-то кодифицированы. – tadman

ответ

3

Вы в основном там. Произвольное ограничение на to_a является нечетным, так как есть много способов получить то же самое. Тем не менее, чтобы исправить свой оригинальный пример:

array = [ ] 
counts.each do |pair| 
    array << pair 
end 

Это грязный способ сделать to_a, но он должен работать. Ваша ошибка пыталась добавить к конкретному элементуarray, а не прилагаться к самому массиву.

Узор использовать при выполнении такого рода операции заключается в следующем:

counts = Hash.new(0) 

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

Там в несколько других вещей, которые вы можете сделать, чтобы уменьшить это и сделать его более рубин, как:

def count_chars(string) 
    string.chars.each_with_object(Hash.new(0)) do |char, counts| 
    case (char) 
    when ' ' 
     # Ignored 
    else 
     counts[char] += 1 
    end 
    end 
end 

Метод each_with_object удобен тем, что он перебирает массив, проходя через объект, что каждая итерация может использовать. Сочетание трюка с Хэшем со значением по умолчанию делает это довольно аккуратным.

Если у вас есть более длинный список символов «игнорировать», выражайте это как массив. string.chars - exclusions может удалить ненужные. Я использовал здесь инструкцию case, чтобы упростить добавление специального поведения.

+1

Спасибо, имеет смысл. Я ценю вашу помощь. –

0

вместо

arr[i].push [key, value] 

использования

arr.push [key, value] 

arr[i] потому, что относится к г-го элемента

0

Я хотел бы сделать что-то вроде этого:

hash = { "H"=> 1, "e"=> 1, "l"=> 3, "o"=> 2, "W"=> 1, "r"=> 1, "d"=> 1 } 

hash.each_with_object([]) { |kv, a| a << kv } 
#=> [["H",1],["e",1],["l",3],["o",2],["W",1],["r",1],["d",1]] 
1
hash = { "H"=> 1, "e"=> 1, "l"=> 3, "o"=> 2, "W"=> 1, "r"=> 1, "d"=> 1 } 

p [*hash] 
# => [["H", 1], ["e", 1], ["l", 3], ["o", 2], ["W", 1], ["r", 1], ["d", 1]] 
0

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

def to_counts_array(counts) 
    counts.map { |k, v| [k, v] } 
end 

h = { "H"=> 1, "e"=> 1, "l"=> 3, "o"=> 2, "W"=> 1, "r"=> 1, "d"=> 1 } 
to_counts_array(h) 

Хотя я, как ответ на @ steenslag также.

0

Другим способом, просто карта для себя:

x.map &:itself #=> [["H", 1], ["e", 1], ["l", 3], ["o", 2], ["W", 1], ["r", 1], ["d", 1]] 
Смежные вопросы