使用.map将JSON扫描到CSV时的额外列,排序顺序丢失

时间:2014-09-15 15:28:28

标签: ruby json csv

我正在编写一个脚本,将JSON数据转换为有序的CSV电子表格。

JSON数据本身不一定包含所有键(电子表格中的某些字段应该说" NA")。

典型的JSON数据如下所示:

json = {"ReferringUrl":"N","PubEndDate":"2010/05/30","ItmId":"347628959","ParentItemId":"46999"}

我有一个电子表格每列中找到的键列表:

keys = ["ReferringUrl", "PubEndDate", "ItmId", "ParentItemId", "OtherKey", "Etc"]

我的想法是我可以像这样迭代JSON的每一行:

parsed = JSON.parse(json)
result = (0..keys.length).map{ |i| parsed[keys[i]] || 'NA'} #add values associated with keys to an array, using NA if no value is present
CSV.open('file.csv', 'wb') do |csv|
    csv << keys #create headings on spreadsheet
    csv << result #load data associated with headings into the next line
end

理想情况下,这会在电子表格中以正确的顺序创建一个包含正确信息的CSV文件。但是,发生的情况是result数据完全无序,并且包含一个我不知道该怎么做的额外列。

查看实际数据,因为实际上有大约100个密钥,而且大多数字段都包含NA,因此很难确定发生了什么。

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

额外列来自0..keys.length,其中包含范围的结尾。 result的最后一个值为parsed[keys[keys.length]],即parsed[nil],即nil。您可以通过直接映射keys

来完全避免这种情况
result = keys.map { |key| parsed.fetch(key, 'NA') }

至于值的随机顺序,我怀疑您没有向我们提供所有相关信息,因为我测试了您的代码,结果与keys的顺序相同。< / p>

答案 1 :(得分:1)

Range有两种可能的符号

..

...

...是排他性的,意味着范围(A ... B)不包括B.

更改为

result = (0...keys.length).map{ |i| parsed[keys[i]] || 'NA'} #add values associated with keys to an array, using NA if no value is present

看看是否会阻止该范围内的最后一个值评估为nil