Руби вводить рекурсию? - PullRequest
2 голосов
/ 15 февраля 2011

Цель состоит в том, чтобы начать с ['a','b','c'] и закончить с {'a'=>{'b'=>{'c'=>{}}}}

итак, получив мои ориентиры, я сделал это:

['a','b','c'].inject({}){|h,v| h.update(v => {})}
# => {"a"=>{}, "b"=>{}, "c"=>{}} 

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

['a','b','c'].inject({}){|h,v| h.update(v => {}); h[v]}
# => {} 

Почему это? Есть идеи, как добиться желаемого результата в элегантном однострочнике?

Ответы [ 2 ]

12 голосов
/ 15 февраля 2011
['a','b','c'].reverse.inject({}) {|r,v| {v=>r}}

Или другими словами:

Создайте хеш с ключом, являющимся первым элементом массива ('c' после его обращения) и начальным числом (пустой хеш) в качестве значения На каждом шаге создайте новый хеш, где ключом является следующее значение из массива, а значением является хеш, возвращенный с предыдущего шага.

Вот результаты после каждой итерации ввода:

r={}, v='c' возвращает {'c'=>{}}

r={'c'=>{}}, v='b' возвращает {'b'=>{'c'=>{}}}

r={'b'=>{'c'=>{}}}, v='a' возвращает {'a'=>{'b'=>{'c'=>{}}}}

5 голосов
/ 15 февраля 2011

Zetetic уже дал вам рабочее решение, но вот причина, по которой ваше не сработало:

['a','b','c'].inject({}){|h,v| h.update(v => {}); h[v]}

Это действительно создаст хеш {'a'=>{'b'=>{'c'=>{}}}}, однако, inject не вернет этот хеш, он вернет результат последнего вызова в блок и это {}, потому что h будет созданным хешем для последнего элемента, то есть {'c' => {}} и, следовательно, h[v] будет {}.

Чтобы увидеть, что нужный хеш действительно создается, но не возвращается, вы можете сначала сохранить передаваемый хеш в переменной, например:

hash = {}
['a','b','c'].inject(hash){|h,v| h.update(v => {}); h[v]}

Таким образом, inject по-прежнему будет возвращать {}, но hash теперь будет содержать хэш {'a'=>{'b'=>{'c'=>{}}}}. При этом решение Zetetic лучше, так как оно более понятно, что происходит. Отключение впрыскиваемого аккумулятора обычно сбивает с толку и доставляет больше хлопот, чем оно того стоит.

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