Наиболее эффективный способ рекурсивного выравнивания вложенного массива в строку, разделенную точками, в Ruby?

Я хочу преобразовать что-то вроде этого:

class NestedItem
  attr_accessor :key, :children
  def initialize(key, &block)
    self.key = key
    self.children = []
    self.instance_eval(&block) if block_given?
  end

  def keys
    [key] + children.keys
  end
end

root = NestedItem.new("root") do
  children << NestedItem.new("parent_a") do
    children << NestedItem.new("child_a")
    children << NestedItem.new("child_c")
  end
  children << NestedItem.new("parent_b") do
    children << NestedItem.new("child_y")
    children << NestedItem.new("child_z")
  end
end

require 'pp'
pp root
#=>
# #<NestedItem:0x1298a0
#  @children=
#   [#<NestedItem:0x129814
#     @children=
#      [#<NestedItem:0x129788 @children=[], @key="child_a">,
#       #<NestedItem:0x12974c @children=[], @key="child_c">],
#     @key="parent_a">,
#    #<NestedItem:0x129738
#     @children=
#      [#<NestedItem:0x129698 @children=[], @key="child_y">,
#       #<NestedItem:0x12965c @children=[], @key="child_z">],
#     @key="parent_b">],
#  @key="root">

В это:

root.keys #=>
[
  "root",
  "root.parent_a",
  "root.parent_a.child_a",
  "root.parent_a.child_c",
  "root.parent_b",
  "root.parent_b.child_y",
  "root.parent_b.child_z",
]

. ... используя рекурсивный метод.

Какой самый простой способ это сделать?

Обновление

Я сделал это:

def keys
  [key] + children.map(&:keys).flatten.map do |node|
    "#{key}.#{node}"
  end
end

Что-нибудь лучше?

1
задан Michael Mrozek 30 August 2010 в 18:53
поделиться

2 ответа

Подойдет ли вам Array.flatten?

self.children.flatten должен возвращать сглаженные результаты.

2
ответ дан 2 September 2019 в 21:42
поделиться

Да, .flatten создаст то, что, я думаю, вам действительно нужно.

Но если вы хотите получить именно ту строку, которую вы набрали, это сделает это:

  def keys x
    here = key
    here = x + '.' + here if x
    [ here ] + children.inject([]) { |m,o| m += o.keys here }
  end

pp root.keys nil

Или, альтернативно, замените последнюю строку в #keys на:

([ here ] + children.map { |o| o.keys here }).flatten
0
ответ дан 2 September 2019 в 21:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: