【问题标题】:Create key, value pair for JSON via nest in D3通过 D3 中的嵌套为 JSON 创建键值对
【发布时间】:2015-07-10 14:20:33
【问题描述】:

我想使用d3.nest() 为 JSON 创建一个键值对。

原始 JSON 如下所示:

[
{
    "Country": "Mexico", 
    "Climate": 100,
    "Safety Index": 50,
    "Life Expectancy": 80,
    "Corruption": 30,
    "Per Capita Income": 20
},
{
    "Country": "UK",
    "Climate": 70,
    "Safety Index": 80,
    "Life Expectancy": 70,
    "Corruption": 70,
    "Per Capita Income": 80
},
{
    "Country": "US",
    "Climate": 80,
    "Safety Index": 70,
    "Life Expectancy": 90,
    "Corruption": 70,
    "Per Capita Income": 80
}
]

我想把它变成这样:

[
{"key": "Mexico", "value":
    [ 
        { "key": "Climate", "value": 100 },
        { "key": "Safety Index", "value": 50 },
        { "key": "Life Expectancy", "value": 80 },
        { "key": "Corruption", "value": 30 },
        { "key": "Per Capita Income", "value": 20 }
    ]},
{"key": "UK", "value":
    [ 
        { "key": "Climate", "value": 70 },
        { "key": "Safety Index", "value": 80 },
        { "key": "Life Expectancy", "value": 70 },
        { "key": "Corruption", "value": 70 },
        { "key": "Per Capita Income", "value": 80 }
    ]},
{"key": "US", "value":
    [ 
        { "key": "Climate", "value": 80 },
        { "key": "Safety Index", "value": 70 },
        { "key": "Life Expectancy", "value": 90 },
        { "key": "Corruption", "value": 70 },
        { "key": "Per Capita Income", "value": 80 }
    ]}
    ]

我的尝试:

var nest = d3.nest()
             .key(function(d) { return d.Country; })
             .entries(data);

我的问题非常基本,因为我是 D3 新手。我应该如何改变 D3 中 JSON 的结构?

编辑

这是根据与此示例类似的不同类别为每个国家/地区创建单独的条形图 (http://bl.ocks.org/mbostock/5872848)。如果有更好的方法我应该考虑这个,请告诉我。

【问题讨论】:

  • 为什么要改造呢?向 D3 提供数据的最简单方法是以类似表格的格式提供数据,就像您的原始 JSON 一样。此外,添加“key”和“value”键有点多余,因为这些信息很容易从原始格式中提取出来。
  • 查看编辑。例如, d3.keys(data[0]) 会引入我需要省略的“Country”。您能否详细说明如何操作?
  • 为什么需要省略“国家”的值?如果您查看您尝试修改的代码示例,该代码也具有“国家/地区”的值。
  • 感谢您的推荐。我明白你在说什么。这是一种更好的方法!
  • 我对我的回答做了一些修改。如果还有什么可以帮助您的,请告诉我。

标签: javascript json d3.js


【解决方案1】:

如果您想要您提供的确切输出,并坚持为此使用嵌套,您可以使用:

var nest = d3.nest()
         .key(function(d) { return d.Country; })
         .rollup(function(d) {
              var countryGroupedObject = d[0];
              return d3.nest()
                       .key(function(innerKey) { return innerKey; })
                       .rollup(function(innerKey) { return countryGroupedObject[innerKey]; })
                       .entries(Object.keys(countryGroupedObject));
          })
         .entries(data);

这里的一个潜在问题是您假设每个国家/地区都是独一无二的(例如,不会有两个“墨西哥”条目)。因此,内部巢穴仅在 d[0] 上运行(这将是给定国家/地区列出的第一项)。

编辑:实际上,这不会是完全您所要求的,国家/地区键:值将存在于内部分组中。如果这是一个问题,可以通过在内部嵌套之前放置以下内容来忽略它: delete countryGroupedObject.Country;

编辑 2: 上面的代码使用嵌套的 nest 函数仅仅是因为问题是这样问的。在实际系统中,内部的 nest 对我来说更适合纯 Javascript,大致如下:

function getGraphParams(countryObj){
    return Object.keys(countryObj)
                   .filter(function(key){ return key !== "Country"; })
                   .map(function(key){ return { key: key, value: countryObj[key] }; })
}

【讨论】:

    【解决方案2】:

    这是一个没有 D3 的解决方案:

    var a = ...; // Original Array of JSON
    var b = [];
    a.forEach(function(item) {
        var r = {};
        r.key = item.Country;
        r.value = [];
        for (var i in item) {
            if (i === "Country") { continue; }
            r.value.push({"key": i, "value": item[i]});
        }
        b.push(r);
    });
    

    不知道为什么你只使用“key”作为你的 key,而“value”作为你的 value 键,这似乎与使用 JSON 中的隐式键和值背道而驰。但我认为你有理由这样做。

    【讨论】:

      【解决方案3】:

      你说:

      如果有更好的方法让我考虑这个问题,请告诉我。

      如果你要改变你的数据结构,为什么不把它改成这样呢?

      [
          ["Mexico", 100, 50, 80, 30, 20],
          ["UK", 70, 80, 70, 70, 80],
          ["US", 80, 70, 90, 70, 80],
      ]
      

      它要小得多,并且没有冗余。

      如果您希望您的结构尽可能接近代码示例的数据结构,我仍然建议您坚持使用您的原始数据结构,因为原始数据结构中的 CSV 文件已转换为漂亮的数据结构与原始 JSON 文件的数据结构非常相似。

      【讨论】:

      • 我对数据的格式有一定的灵活性。我会研究这两种选择,因为我需要更多的练习!再次感谢您的建议。
      • @Zach 您可能还想查看johnslegers.com/map 的代码。虽然我使用的 GUI 与您的想法完全不同,但正在处理的数据类型与您的有些相似,而且我还使用 JSON 文件作为源。
      • 感谢提供如何处理 JSON 数据的示例。
      • @Zach :请不要介意我在该示例中使用的编码风格。代码相当难看,这也是我还没放到 Github 上的原因。尽管如此,它应该可以在每个现代浏览器上完美运行。
      • 没问题!重要的是总体思路。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-24
      • 1970-01-01
      • 2018-01-30
      • 2016-04-25
      • 2021-12-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多