如何从json文件中收集标头

问题描述 投票:0回答:3

我正在尝试将json文件更改为CSV。这是我的Json:

[
  {
    "id": 0,
    "email": "[email protected]",
    "tags": [
      "consectetur",
      "quis"
    ],
    "profiles": {
      "facebook": {
        "id": 0,
        "picture": "//fbcdn.com/a2244bc1-b10c-4d91-9ce8-184337c6b898.jpg"
      },
      "twitter": {
        "id": 0,
        "picture": "//twcdn.com/ad9e8cd3-3133-423e-8bbf-0602e4048c22.jpg"
      }
    }
  },
  {
    "id": 1,
    "email": "[email protected]",
    "tags": [
      "veniam",
      "elit",
      "mollit"
    ],
     "profiles": {
       "facebook": {
         "id": 1,
         "picture": "//fbcdn.com/12e070e0-21ea-4663-97d0-46bc9c7b67a4.jpg"
       },
       "twitter": {
         "id": 1,
         "picture": "//twcdn.com/3057792f-5dfb-4c4b-86b5-cce4d6bbf7ac.jpg"
       }
     }
   }
 ]

我首先想要的是收集标题。这是我试过的:

json = JSON.parse(File.open("live.json").read)
headings = SortedSet.new
json.each do |hash|
  headings.merge(hash.values)
end

它让我回到#<SortedSet:0x007fa592128088>

然后,我试图了解发生了什么(我没有顺便说一句)但我看到当我要求我的json.values时,我没有嵌套值。这就是我所拥有的:

id
email
tags
profiles

预期产出为:

id, email, tags, profiles.facebook.id, profiles.facebook.picture, profiles.twitter.id, profiles.twitter.picture

所以我的问题是,有人知道如何获得这些标题吗?有没有一种简单的方法可以在不使用SortedSet的情况下获取它们?

非常感谢 !

ruby-on-rails ruby
3个回答
1
投票

使用get_recursive_keys方法获取嵌套密钥

def get_recursive_keys(hash, nested_key=nil)
  hash.each_with_object([]) do |(k,v),keys|      
    k = "#{nested_key}.#{k}" unless nested_key.nil?
    if v.is_a? Hash
      keys.concat(get_recursive_keys(v, k))
    else
      keys << k
    end
  end
end

然后在你的排序集中附加如下:

json = JSON.parse(File.open("live.json").read)
headings = SortedSet.new
json.each do |hash|
  headings.merge(get_recursive_keys(hash))
end

现在Key的标题:

#<SortedSet: {"email", "id", "profiles.facebook.id", "profiles.facebook.picture", "profiles.twitter.id", "profiles.twitter.picture", "tags"}>

0
投票

对于任何嵌套级别的哈希:

get = ->(hash, prefix = nil) do
        hash.flat_map do |k, v|
          v.is_a?(Hash) ? get.(v, k) : [prefix, k].compact.join('.')
        end
      end

json.map(&get)
#⇒ array of titles in each hash
json.map(&get).first
#⇒ ["id", "email", "tags",
#   "facebook.id", "facebook.picture",
#   "twitter.id", "twitter.picture"]

0
投票

你可以这样做:

json = <<-END
[
  {
    "id": 0,
    "email": "[email protected]",
    "tags": [
      "consectetur",
      "quis"
    ],
    "profiles": {
      "facebook": {
        "id": 0,
        "picture": "//fbcdn.com/a2244bc1-b10c-4d91-9ce8-184337c6b898.jpg"
      },
      "twitter": {
        "id": 0,
        "picture": "//twcdn.com/ad9e8cd3-3133-423e-8bbf-0602e4048c22.jpg"
      }
    }
  },
  {
    "id": 1,
    "email": "[email protected]",
    "tags": [
      "veniam",
      "elit",
      "mollit"
    ],
     "profiles": {
       "facebook": {
         "id": 1,
         "picture": "//fbcdn.com/12e070e0-21ea-4663-97d0-46bc9c7b67a4.jpg"
       },
       "twitter": {
         "id": 1,
         "picture": "//twcdn.com/3057792f-5dfb-4c4b-86b5-cce4d6bbf7ac.jpg"
       }
     }
   }
 ]
END

CSV.generate do |csv| 
  csv << [:id, :email, :tags, :profiles] # add headers with order
  JSON.parse(json).each do |item| 
    csv << [item['id'], item['email'], item['tags'].join(','), item['profiles']] # add rows with the same order
  end
end

它会给你以下csv:

id,email,tags,profiles
0,[email protected],"consectetur,quis","{""facebook""=>{""id""=>0, ""picture""=>""//fbcdn.com/a2244bc1-b10c-4d91-9ce8-184337c6b898.jpg""}, ""twitter""=>{""id""=>0, ""picture""=>""//twcdn.com/ad9e8cd3-3133-423e-8bbf-0602e4048c22.jpg""}}"
1,[email protected],"veniam,elit,mollit","{""facebook""=>{""id""=>1, ""picture""=>""//fbcdn.com/12e070e0-21ea-4663-97d0-46bc9c7b67a4.jpg""}, ""twitter""=>{""id""=>1, ""picture""=>""//twcdn.com/3057792f-5dfb-4c4b-86b5-cce4d6bbf7ac.jpg""}}"

但您必须决定如何处理配置文件。

更新

CSV.generate do |csv| 
  csv << ['id', 'email', 'tags', 'profiles.facebook.id', 'profiles.facebook.picture', 'profiles.twitter.id', 'profiles.twitter.picture'] 
  JSON.parse(json).each do |item| 
    csv << [item['id'], item['email'], item['tags'].join(','), item['profiles']['facebook']['id'], item['profiles']['facebook']['picture'], item['profiles']['twitter']['id'], item['profiles']['twitter']['picture']] 
  end
end

将导致

id,email,tags,profiles.facebook.id,profiles.facebook.picture,profiles.twitter.id,profiles.twitter.picture
0,[email protected],"consectetur,quis",0,//fbcdn.com/a2244bc1-b10c-4d91-9ce8-184337c6b898.jpg,0,//twcdn.com/ad9e8cd3-3133-423e-8bbf-0602e4048c22.jpg
1,[email protected],"veniam,elit,mollit",1,//fbcdn.com/12e070e0-21ea-4663-97d0-46bc9c7b67a4.jpg,1,//twcdn.com/3057792f-5dfb-4c4b-86b5-cce4d6bbf7ac.jpg
© www.soinside.com 2019 - 2024. All rights reserved.