【问题标题】:How do I convert company.address.city into an object with Ruby on Rails如何使用 Ruby on Rails 将 company.address.city 转换为对象
【发布时间】:2019-11-29 13:39:27
【问题描述】:

我有一些参数,我正在尝试从即构建深层嵌套的 json 对象:company.address.city company.address.state

这是我的参数:

{"business_type"=>"company", "company.address.city"=>"Gold Coast", "company.address.line1"=>"123 fake street", "company.address.state"=>"QLD", "company.name"=>"test"}

我期待这样的事情:

business_type: "company",
company{
  address{
     city: "Gold Coast",
     line1: "123 fake street",
     state: "QLD",
  },
name: "test"
}

【问题讨论】:

    标签: ruby-on-rails json ruby parameters


    【解决方案1】:

    以方法的形式,以备不时之需

    h = {"business_type"=>"company", "company.address.city"=>"Gold Coast", "company.address.line1"=>"123 fake street", "company.address.state"=>"QLD", "company.name"=>"test"}
    
    def flatten_keys(hash)
      hash.each_with_object({}) do |(key,value), all|
        parts = key.split('.').map!(&:to_sym)
        new = parts[0...-1].inject(all) { |h, k| h[k] ||= {} }
        new[parts.last] = value
      end
    end
    
    flatten_keys(h)
    

    这个打印出来

    => {:business_type=>"company", :company=>{:address=>{:city=>"Gold Coast", :line1=>"123 fake street", :state=>"QLD"}, :name=>"test"}}
    

    希望对你有帮助

    【讨论】:

      【解决方案2】:

      这不是最优雅的,但它确实有效:

      input = {"business_type"=>"company", "company.address.city"=>"Gold Coast", "company.address.line1"=>"123 fake street", "company.address.state"=>"QLD", "company.name"=>"test"}
      
      res = input.reduce({}) do |memo, (keys_str, val)|
        keys = keys_str.split(".")
        last_key = keys[-1]
        hsh = memo
        keys[0...-1].each do |key|
          hsh[key] ||= {}
          hsh = hsh[key]
        end
        hsh[last_key] = val
        memo
      end
      
      puts res
      

      哪个打印:

      {"business_type"=>"company", "company"=>{"address"=>{"city"=>"Gold Coast", "line1"=>"123 fake street", "state"= >“QLD”},“名称”=>“测试”}}

      【讨论】:

      • 钉了它.. 完美运行 - 但是 kkp 的答案也是如此,我选择它作为答案纯粹是因为我理解它。但是对于其他需要答案的人来说,这很好用。
      【解决方案3】:

      Pure Ruby:您可以为深度赋值定义自定义方法,例如受https://stackoverflow.com/a/54122742 启发的这样:

      def nested_set(h, keys, value)
        # keys = keys.map(&:to_sym)
        last_key = keys.pop
        position = h
        keys.each do |key|
          position[key] = {} unless position[key].is_a? Hash
          position = position[key]
        end
        position[last_key] = value
      end
      

      然后,将parameters 作为数据输入,您可以在需要时轻松调用它:

      parameters.each.with_object({}) { |(k, v), res| nested_set(res, k.split('.'), v) }
      
      #=> {"business_type"=>"company", "company"=>{"address"=>{"city"=>"Gold Coast", "line1"=>"123 fake street", "state"=>"QLD"}, "name"=>"test"}}
      


      或者定义一个更方便的方法
      def do_that_on parameters
        parameters.each.with_object({}) { |(k, v), res| nested_set(res, k.split('.'), v) }
      end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-04-02
        • 1970-01-01
        • 2017-01-13
        • 1970-01-01
        • 2017-05-05
        • 2014-06-04
        • 1970-01-01
        • 2016-12-23
        相关资源
        最近更新 更多