Ruby on rails 如何从json文件中收集标题
我正在尝试将json文件更改为CSV。以下是我的Json:Ruby on rails 如何从json文件中收集标题,ruby-on-rails,ruby,Ruby On Rails,Ruby,我正在尝试将json文件更改为CSV。以下是我的Json: [ { "id": 0, "email": "colleengriffith@quintity.com", "tags": [ "consectetur", "quis" ], "profiles": { "facebook": { "id": 0, "picture": "//fbcdn.com/a2244bc1-b10c-
[
{
"id": 0,
"email": "colleengriffith@quintity.com",
"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": "maryellengriffin@ginkle.com",
"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
它返回给我#
然后,我试图理解发生了什么(顺便说一句,我没有),但我发现当我要求我的json.values
时,我没有嵌套的值。以下是我所拥有的:
id
email
tags
profiles
预期产出为:
id, email, tags, profiles.facebook.id, profiles.facebook.picture, profiles.twitter.id, profiles.twitter.picture
所以我的问题是,有人知道如何获得这些标题吗?有没有一种不使用SortedSet的简单方法来获取它们
非常感谢 您可以这样做:
json = <<-END
[
{
"id": 0,
"email": "colleengriffith@quintity.com",
"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": "maryellengriffin@ginkle.com",
"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
json = JSON.parse(File.open("live.json").read)
headings = SortedSet.new
json.each do |hash|
headings.merge(get_recursive_keys(hash))
end
但你必须决定如何处理个人资料
已更新
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
对于任何嵌套级别的哈希:
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"]
使用Get\u recursive\u 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
现在键的标题:
#<SortedSet: {"email", "id", "profiles.facebook.id", "profiles.facebook.picture", "profiles.twitter.id", "profiles.twitter.picture", "tags"}>
#
您希望得到什么样的确切输出?请说明您的预期输出。您不可能通过调用hash.values
获得id
,电子邮件
等。我对其进行了编辑,以向您显示我希望得到的输出。谢谢您的回答。我已经决定了如何处理个人资料,我需要收集这些资料,收集的方式与我的输出方式相同。谢谢你回答这个问题,它确实起到了作用。然而,你写的东西在我脑子里不是那么清楚。。。你能再给我解释一下吗?我不知道我能补充些什么使它更明确get
lambda递归提取密钥并用点连接它们。我喜欢您编写代码的方式。但我有一个问题。当我运行你的代码时,我的标题变量等于
你知道吗?我做错什么了吗?@RaphaëlFOSSE嘿,我只是用p标题而不是puts标题:)对!哈哈,但是,标签
没有出现在我的输出中,正如我所看到的,你的标签也没有出现在我的输出中。哦,没有注意到,对不起。再次感谢!您正在使用外部局部变量滥用each
,请使用json.each_with_object(SortedSet.new){| hash,set | set.merge(get_recursive_keys(hash))}
。
json = JSON.parse(File.open("live.json").read)
headings = SortedSet.new
json.each do |hash|
headings.merge(get_recursive_keys(hash))
end
#<SortedSet: {"email", "id", "profiles.facebook.id", "profiles.facebook.picture", "profiles.twitter.id", "profiles.twitter.picture", "tags"}>