如何从父节点搜索数组的嵌套散列和散列数组以及仅 return 匹配对象?

How to search nested hash of arrays and arrays of hash and only return matching object from the parent node?

假设我有下面的 ruby 哈希嵌套

hash_or_array = [{
  "book1" => "buyer1",
  "book2" => {
    "book21" => "buyer21", "book22" => ["buyer23", "buyer24", true]
  },
  "book3" => {
    "0" => "buyer31", "1" => "buyer32", "2" => "buyer33", 
    "3" => [{
      "4" => "buyer34",
      "5" => [10, 11],
      "6" => [{
        "7" => "buyer35"
      }]
    }]
  },
  "book4" => ["buyer41", "buyer42", "buyer43"],
  "book5" => {
    "book5,1" => "buyer5"
  }
}]

我想搜索匹配 buyer35 的字符串。在比赛中,我希望它 return 以下结果

"book3" => {
    "3" => [{
      "6" => [{
        "7" => "buyer35"
      }]
    }]
  }]

应省略所有、其他不匹配的键、值、数组。我有下面的例子,但它不太管用

def search(hash)
    hash.each_with_object({}) do |(key, value), obj|
      if value.is_a?(Hash)
        returned_hash = search(value)
        obj[key] = returned_hash unless returned_hash.empty?
      elsif value.is_a?(Array)
        obj[key] = value if value.any? { |v| matches(v) }
      elsif matches(key) || matches(value)
        obj[key] = value
      end
    end
end


def matches(str)
    match_criteria = /#{Regexp.escape("buyer35")}/i
    (str.is_a?(String) || str == true || str == false) && str.to_s.match?(match_criteria)
end



....
=> search(hash_or_array)

感谢任何帮助。我意识到,我需要使用递归,但不太清楚如何 build/keep 从父节点跟踪匹配的节点。

可以使用下面的递归方法。

def recurse(obj, target)
  case obj
  when Array
    obj.each do |e|
      case e
      when Array, Hash
        rv = recurse(e, target)
        return [rv] unless rv.nil?
      when target
        return e
      end
    end
  when Hash
    obj.each do |k,v|
      case v
      when Array, Hash
        rv = recurse(v, target)
        return {k=>rv} unless rv.nil?
      when target
        return {k=>v}
      end
    end
  end
  nil
end
recurse(hash_or_array, "buyer35")
  #=> [{"book3"=>{"3"=>[{"6"=>[{"7"=>"buyer35"}]}]}}]
recurse(hash_or_array, "buyer24")
  #=>[{"book2"=>{"book22"=>"buyer24"}}]
recurse(hash_or_array, "buyer33")
  #=> [{"book3"=>{"2"=>"buyer33"}}]
recurse(hash_or_array, 11)
  #=> [{"book3"=>{"3"=>[{"5"=>11}]}}]
recurse(hash_or_array, "buyer5")
  #=>[{"book5"=>{"book5,1"=>"buyer5"}}]

如果需要,可以这样写,例如

recurse(hash_or_array, "buyer35").first
  #=> {"book3"=>{"3"=>[{"6"=>[{"7"=>"buyer35"}]}]}}