迭代一次更改一个Ruby哈希值中的每个值

时间:2016-10-18 09:39:45

标签: ruby recursion hash

我有一个问题,我想:

1遍历嵌套哈希,因此可以有数组,哈希值或值等 2 - 对于每个值,我发现用字符串" text"替换它,但只有一次,所以对于每次迭代,只有一个值被改变而其余的哈希是完整的 3 - 在函数中使用这个新哈希

问题在于,当我递归地执行此操作时,我或者只获得部分哈希值,因为递归函数不知道更宽的上下文,或者我得到原始哈希值,所有值都更改而不是只有一个,但我可以& #39;想到没有递归就这样做

我可以提出什么问题?

由于

编辑:好的人们希望我发布代码并低估我,即使我问的是这个概念是否可行而不是解决方案!但不管这是我最近的尝试,但是如果所有人都在询问的话,那么看看是什如果它可以递归:

我试图做的是递归地找到要更改的值,并记住它们的映射,因为我这样做,我可以使用该痕迹的痕迹来更改原始哈希

def iterate_and_test_within_hash endpoint, hashbody, teststrings
p "#{hashbody}"
for payload in teststrings do
outhash=scrolltests hashbody, nil, hashbody, payload
end
end

def scrolltests parenthash, parentkeys, hashin, teststring
  if !parentkeys
  parentkeys=[]
 end
 # outhash=Marshal.load( Marshal.dump(parenthash) )
 outhash=parenthash
# localparentkeys=Marshal.load( Marshal.dump(parentkeys) )


p parentkeys
    hashin.each do |k, v|
  if v.is_a?(String) || v.is_a?(Numeric)

    parentkeys.concat([k])
    p parentkeys
    parentkeys.map!(&:to_sym)
    key = parentkeys.pop

    begin

      parentkeys.inject(outhash, :fetch)[key] = teststring
    rescue => e
        key = parentkeys.pop
      retry
    end

    p outhash
    parentkeys.concat([k])
    scrolltests(parenthash, parentkeys,v, teststring)
  elsif v.is_a?(Array)
      v.flatten.each { |x|
        if x.is_a?(Hash)
          # parentkeys.concat([x])
          scrolltests(parenthash, parentkeys,x, teststring)
        end
        }
  end
end
end


with this input hash:
{
      :properties=>{
          :one=>'extra',
          :headers=>{
              :type=>'object',
              :type1=>'object2'
          },
          :entity=>{
              :type=>'entype'
          },
      },
      :sec_prop=>'hmmm'
  }

它给出了这些结果,因此在递归之间没有正确跟踪密钥,我怀疑是因为某些元素被放入了错误的级别,放在父母不在的地方。有一个父,但前一个元素,同一层次结构上的元素同时被更改

[]
[:properties]
[:properties, :one]
{:properties=>{:one=>"<PLAINTEXT>", :headers=>{:type=>"object", :type1=>"object2"}, :entity=>{:type=>"entype"}}, :sec_prop=>"hmmm"}
[:properties, :headers]
[:properties, :headers, :type]
{:properties=>{:one=>"extra", :headers=>{:type=>"<PLAINTEXT>", :type1=>"object2"}, :entity=>{:type=>"entype"}}, :sec_prop=>"hmmm"}
[:properties, :headers, :type1]
{:properties=>{:one=>"extra", :headers=>{:type=>"<PLAINTEXT>", :type1=>"<PLAINTEXT>"}, :entity=>{:type=>"entype"}}, :sec_prop=>"hmmm"}
[:properties, :headers, :entity]
[:properties, :headers, :entity, :type]
{:properties=>{:one=>"extra", :headers=>{:type=>"object", :type1=>"object2", :entity=>"<PLAINTEXT>"}, :entity=>{:type=>"entype"}}, :sec_prop=>"hmmm"}
[:properties, :sec_prop]
{:properties=>{:one=>"extra", :headers=>{:type=>"object", :type1=>"object2"}, :entity=>{:type=>"entype"}, :sec_prop=>"<PLAINTEXT>"}, :sec_prop=>"hmmm"}

1 个答案:

答案 0 :(得分:0)

如果有人遇到类似的问题,

解决它(除了目前的数组或哈希)。对我来说很大的问题,我必须记住它是如何到达特定的&#34;层&#34;递归映射它应该写入主散列,并且ruby通过引用而不是对象传递,这意味着当在树状对象中行进时,一个分支将拧紧下一个分支的参数

代码:

def scrolltests parenthash, parentkeys, hashin, teststring
  keys=Marshal.load( Marshal.dump(parentkeys) )

hashin.each do |k, v|
  if !keys
    keys=[]
  end
  keys.to_a

  outhash=Marshal.load( Marshal.dump(parenthash) )

  p keys
  if v.is_a?(String) || v.is_a?(Numeric)
    keys.concat([k])
      p keys
    keys.map!(&:to_sym)
      key = keys.pop
      begin
        keys.inject(outhash, :fetch)[key] = teststring
      rescue => e
        key =keys.pop
        retry
      end

    # end

    p outhash

  elsif v.is_a?(Hash)
    keys.concat([k])
      scrolltests(parenthash, keys,v, teststring)
    keys.pop

  elsif v.is_a?(Array)
      v.flatten.each { |x|
        if x.is_a?(Hash)
          scrolltests(parenthash, keys,x, teststring)
        end
        }
  end



end


end

以便输入测试hash / json为

{
  :properties=>{
      :one=>'extra',
      :headers=>{
          :type=>'object',
          :type1=>'object2'
      },
      :entity=>{
          :type=>'entype'
      },
  },
  :sec_prop=>'hmmm'
  }

输出显示单独更改每个元素,如下所示:

"{:properties=>{:one=>\"extra\", :headers=>{:type=>\"object\", :type1=>\"object2\"}, :entity=>{:type=>\"entype\"}}, 


{:properties=>{:one=>"<PLAINTEXT>", :headers=>{:type=>"object", :type1=>"object2"}, :entity=>{:type=>"entype"}}, :sec_prop=>"hmmm"}

{:properties=>{:one=>"extra", :headers=>{:type=>"<PLAINTEXT>", :type1=>"object2"}, :entity=>{:type=>"entype"}}, :sec_prop=>"hmmm"}

{:properties=>{:one=>"extra", :headers=>{:type=>"object", :type1=>"<PLAINTEXT>"}, :entity=>{:type=>"entype"}}, :sec_prop=>"hmmm"}

{:properties=>{:one=>"extra", :headers=>{:type=>"object", :type1=>"object2"}, :entity=>{:type=>"<PLAINTEXT>"}}, :sec_prop=>"hmmm"}

{:properties=>{:one=>"extra", :headers=>{:type=>"object", :type1=>"object2"}, :entity=>{:type=>"entype"}}, :sec_prop=>"<PLAINTEXT>"}