【问题标题】:JSON field into CSVJSON 字段转换为 CSV
【发布时间】:2018-12-13 12:46:24
【问题描述】:

我有一个 Postgres JSON 字段 - 在对其调用 JSON.parse 之后,我得到一个哈希数组 - 这是一个示例:

[{"fips": "12345, "city": "Atlanta", "state": "IL", "zip": "61723"}, {"fips": "24567", "city": "Lincoln", "state": "IL", "zip": "62656"}]

我有一种提取城市、州和邮政编码的方法。我有另一种将其插入 CSV 的方法。这是我的提取方法:

def address(in_arr)
  in_arr.map do |h|
    h.select { |k, v| "#{k}: #{v}\n" unless k.eql?('fips') }
  end
end

我需要 CSV 文件中的单元格如下所示:

city: Atlanta
state: IL
zip: 61723

等等……

但我得到了:

[{"city"=>"Atlanta"}, {"state"=>"IL"}, {"zip"=>"61723"}]

我尝试过 map 而不是 select,我尝试在内部 select 中插入 puts等,但它永远不会正确显示。任何想法将不胜感激。

【问题讨论】:

    标签: ruby-on-rails json ruby


    【解决方案1】:
    input.map { |hash| hash.to_a[1..-1].map { |e| e.join(': ') } }
    #⇒ [["city: Atlanta", "state: IL", "zip: 61723"],
    #   ["city: Lincoln", "state: IL", "zip: 62656"]]
    

    或者

    input.map do |hash|
      hash.reject { |k, _| k == :fips }.map(&:zip).map { |e| e.join(': ') }
    end
    

    或者

    keys = %i|city state zip|
    input.map do |hash|
      keys.zip(hash.values_at(*keys)).map { |e| e.join(': ') }
    end
    

    【讨论】:

      【解决方案2】:

      您的数据格式如下,

       data = [{"city"=>"Atlanta"}, {"state"=>"IL"}, {"zip"=>"61723"}]
      

      创建 csv 以写入以下格式的文件,

      CSV.generate(headers: false) { |csv| hash.map(&:to_a).each { |row| csv << row } }
      
      # => "\"[\"\"city\"\", \"\"Atlanta\"\"]\"\n\"[\"\"state\"\", \"\"IL\"\"]\"\n\"[\"\"zip\"\", \"\"61723\"\"]\"\n"
      

      CSV.generate 是将数据转换为csv 格式的正确方法。

      【讨论】:

        【解决方案3】:

        解决您的问题的最简单方法是只返回当前哈希的值,假设您获得了正确的哈希。您可以使用ruby API 中定义的哈希值方法。

        通过执行以下操作,我能够达到预期的结果,

        ex_hash = [
                  {'fips': '12345', 'city': 'Atlanta', 'state': 'IL', 'zip': '61723'}, 
                  {'fips': '24567', 'city': 'Lincoln', 'state': 'IL', 'zip': '62656'}
                ]
        
        keys_to_extract = [:city, :state, :zip]
        
        address_values = []
        ex_hash.each do |h| # iterate over the hash
          address_values << h.select { |k,_| keys_to_extract.include? k }.values # extract values 
        end
        
        puts address_values.inspect # [["Atlanta", "IL", "61723"], ["Lincoln", "IL", "62656"]]
        

        或者另外如 Aleksei Matiushkin 在 cmets 中提到的那样。

        address_values = ex_hash.map { |h| h.select { |k,_| keys_to_extract.include? k }.value }
        

        【讨论】:

        • 你在滥用map 进行迭代,它是零意义的。 Ruby 中的迭代将使用each 完成。请改用address_values = ex_hash.map { |h| h.select { |k,_| keys_to_extract.include? k }.value }。
        • @AlekseiMatiushkin 好点。我们不需要返回新数组的额外开销。我将在上面对每个进行修改,然后在编辑后的评论中添加您的建议。
        猜你喜欢
        • 2020-01-18
        • 2020-02-17
        • 2015-08-23
        • 2019-06-20
        • 1970-01-01
        • 1970-01-01
        • 2019-08-21
        • 2011-04-27
        相关资源
        最近更新 更多