2010-09-09 4 views
1

Мне нужно преобразовать ["a", "b", "c", "d"] в {:a => {:b => {:c => "d" }}}?Преобразование «Array to Hash» в Ruby

Любые идеи?

Благодаря

+1

Я бы быть немного осторожным: как вы знаете, что оно должно быть преобразовано в '{: а => {: Ь => { : c => "d"}}} 'а не' {: a =>: b,: c =>: d} '? –

ответ

3

мне нравится:

class Array 
    def to_weird_hash 
    length == 1 ? first : { first.to_sym => last(length - 1).to_weird_hash } 
    end 
end 

["a", "b", "c", "d"].to_weird_hash 

Что вы думаете?

+1

Какая версия рубина это допустимо? –

+1

это рубин-1.8.7 – jordinl

+1

OK. Я получаю undefined метод 'from' в обоих 1.8.7 и 1.9.2 –

4

смешно

ruby-1.8.7-p174 > ["a", "b", "c", "d"].reverse.inject{|hash,item| {item.to_sym => hash}} 
=> {:a=>{:b=>{:c=>"d"}}} 
+0

Я позволил себе упростить код. –

+0

спасибо! я не знал, что инъекция имела эту приятную особенность. – hellvinz

2

Если вам нужно сделать, это ровно 4 элементов, легко прийти просто написать его (и вполне читаемым тоже)

>> A=["a", "b", "c", "d"] 
=> ["a", "b", "c", "d"] 
>> {A[0].to_sym => {A[1].to_sym => {A[2].to_sym => A[3]}}} 
=> {:a=>{:b=>{:c=>"d"}}} 

В противном случае, это будет работать массивы переменной длины

>> ["a", "b", "c", "d"].reverse.inject(){|a,e|{e.to_sym => a}} 
=> {:a=>{:b=>{:c=>"d"}}} 
>> ["a", "b", "c", "d", "e", "f"].reverse.inject(){|a,e|{e.to_sym => a}} 
=> {:a=>{:b=>{:c=>{:d=>{:e=>"f"}}}}} 
+0

Мне это нужно с несколькими элементами. – retro

+1

@retro, не уверен, что вы имеете в виду более чем одним элементом. Я добавил способ сделать это с массивами переменной длины –

+0

Я имел в виду, что у меня есть несколько элементов в массиве ввода. Также хорошее решение. – retro

0

Я понял это с помощью IRC.

x = {}; a[0..-3].inject(x) { |h,k| h[k.to_sym] = {} }[a[-2].to_sym] = a[-1]; x 

Второй способ с рекурсивным (лучше)

def nest(a) 
    if a.size == 2 
    { a[0] => a[1] } 
    else 
    { a[0] => nest(a[1..-1]) } 
    end 
end