修改多维符号数组

时间:2016-01-16 20:08:49

标签: arrays ruby

目前我有类似的事情:

arr = [
  :name,
  :address,
  cards_attributes: [
    :last_name,
    :first_name,
    phones_attributes: [
      :number,
      :_destroy
    ],
    emails_attributes: [
      :number,
      :_destroy
    ],
    ...
  ]
]

...我希望把它变成像:

arr = [
  :id, # <- new!
  :name,
  :address,
  cards_attributes: [
    :id, # <- new!
    :last_name,
    :first_name,
    phones_attributes: [
      :id, # <- new!
      :number,
      :_destroy
    ],
    emails_attributes: [
      :id, # <- new!
      :number,
      :_destroy
    ],
    ...
  ]
]

我知道我可以使用arr.push(:id)将新符号添加到第一级,但如何将元素添加到子哈希中?

2 个答案:

答案 0 :(得分:3)

def add_id(collection)
  collection.unshift(:id) if collection.respond_to?(:unshift)

  collection.each do |key, value|
    add_id(key)   if key.respond_to?(:each)
    add_id(value) if value.respond_to?(:each)
  end
end

编辑:对于以下更新

  

“我的问题实际上更多是关于如何优雅地访问子哈希?”

我们可以使用相同的一般想法。由于您没有指定要对哈希执行的操作,因此该方法将需要一个块:

def traverse(collection)
  yield collection if collection.is_a? Hash

  collection.each do |key, value|
    traverse(key)   if key.respond_to?(:each)
    traverse(value) if value.respond_to?(:each)
  end
end

traverse(arr) { |hash| puts hash }

答案 1 :(得分:1)

这是对编辑前原始问题的回答

arr.unshift(:id)
arr[-1][:cards_attributes].unshift(:id)
arr[-1][:cards_attributes][-1][:phones_attributes].unshift(:id)

或者如果您不喜欢使用索引,

arr.unshift(:id)
arr.last[:cards_attributes].unshift(:id)
arr.last[:cards_attributes].last[:phones_attributes].unshift(:id)

或者,你也可以这样做:

arr.unshift(:id)
arr.dig(-1, :cards_attributes).unshift(:id)
arr.dig(-1, :cards_attributes, -1, :phones_attributes).unshift(:id)