【发布时间】:2021-09-02 03:36:15
【问题描述】:
首先,如果这个问题已经存在,请见谅,我在这里深入寻找解决方案,但我已经找到了,但我觉得这是一个如此普遍的问题,找不到任何东西似乎很奇怪这里...
我的斗争如下:给定一个哈希,我需要将所有 PATHS 作为字符串数组返回到每个叶子;所以,例如:
-
{:a=> 1}给['a'] -
{:a=>{:b=>3, :c=>4}返回一个包含 两个 结果的数组:["a.b", "a.c"] -
{:a=>[1, {:b=>2}]}将导致["a.0", "a.1.b"]等等……
我只找到了部分解决方案,并且有几十个代码行。像这样
def pathify
self.keys.inject([]) do |acc, element|
return acc if element.blank?
if !(element.is_a?(Hash) || element.is_a?(Array))
if acc.last.is_a?(Array)
acc[acc.size-1] = acc.last.join('.')
else
acc << element.to_s
end
end
if element.is_a?(Hash)
element.keys.each do |key|
if acc.last.is_a?(Array)
acc.last << key.to_s
else
acc << [key.to_s]
end
element[key].pathify
end
end
if element.is_a?(Array)
acc << element.map(&:pathify)
end
acc
end
end
但它并非在所有情况下都有效,而且效率极低。总结:有没有办法“路径化”一个哈希,以字符串数组的形式返回每个叶子的所有路径? 感谢您的帮助!
已编辑 添加一些规格
for {} it returns []
for {:a=>1} it returns ["a"]
for {:a=>1, :b=>1} it returns ["a", "b"]
for {:a=>{:b=>1}} it returns ["a.b"] (FAILED - 1) got: ["a"]
for {:a=>{:b=>1, :c=>2}} it returns ["a.b", "a.c"] (FAILED - 2) got: ["a"]
for {:a=>[1]} it returns ["a.0"] (FAILED - 3) got: ["a"]
for {:a=>[1, "b"]} it returns ["a.0", "a.1"] (FAILED - 4) got: ["a"]
【问题讨论】:
-
它不适用于哪种情况,您认为它效率低下的基准是什么?我的怀疑是,事实上,你的抱怨只是上面的代码看起来“复杂”,你想要一个更短的解决方案。
-
好点。让我添加一些规格以在失败时显示
-
另外:您希望如何区分
{'a' => { '1' => 'b'}}和{'a' => ['b']}?这两个键都将由a.1表示。如果您希望哈希键是符号而不是字符串,或者这种情况根本不会发生,那么这可能不是问题。 -
也是个好问题。让我们假设键永远不会是整数。只有字符串/符号,所以 1 将始终是数组的第二个元素。没有日期,也没有特殊字符。只是
[a-Z-_]
标签: ruby-on-rails ruby hash tree