使用动态密钥对嵌套对象进行分组(使用Lodash)

时间:2016-05-03 18:53:19

标签: javascript arrays javascript-objects lodash

我查询Firebase以获取一些数据投入Chart.js。以下是我如何列出我的数据:

{
  "20160428": {
    "follow": 13,
    "host": 6,
    "raid": 1,
    "substreak": 1,
    "tip": 1
  },
  "20160429": {
    "follow": 15,
    "host": 21,
    "raid": 2,
    "substreak": 4
  },
  "20160430": {
    "follow": 4
  },
  "20160501": {
    "follow": 11,
    "host": 15,
    "subscription": 4,
    "substreak": 5
  },
  "20160502": {
    "follow": 2,
    "host": 6,
    "subscription": 1,
    "substreak": 4
  },
  "20160503": {
    "follow": 2
  }
}

正如您所看到的,每个对象都被时间戳键入,事件并不总是出现在每个对象中(但事件数量有限)。以下是我希望数据的外观,以便将其输入Chart.js:

labels: ["20160428", "20160429", "20160430", ...]

{
  "follow": [13, 15, 4, 11, 2, 2],
  "host": [6, 21, 0, 15, 6, 0],
  "raid": [1, 2, 0, 0, 0, 0],
  "subscription": [0, 0, 0, 4, 1, 0]
  "substreak": [1, 4, 0, 5, 4, 0]
  "tip": [1, 0, 0, 0, 0, 0]
}

我使用过Lodash的groupBy和类似的功能,但我不确定我是否在正确的轨道上。我不介意每次活动x次这样做,但此时我无法改变架构。

3 个答案:

答案 0 :(得分:1)

你可以使用普通的javascript和一些循环。



var data = { "20160428": { "follow": 13, "host": 6, "raid": 1, "substreak": 1, "tip": 1 }, "20160429": { "follow": 15, "host": 21, "raid": 2, "substreak": 4 }, "20160430": { "follow": 4 }, "20160501": { "follow": 11, "host": 15, "subscription": 4, "substreak": 5 }, "20160502": { "follow": 2, "host": 6, "subscription": 1, "substreak": 4 }, "20160503": { "follow": 2 } },
    grouped = {}

Object.keys(data).forEach(function (k) {
    ["follow", "host", "raid", "substreak", "tip"].forEach(function (kk) {
        grouped[kk] = grouped[kk] || [];
        grouped[kk].push(data[k][kk] || 0);
    });
});

document.write('<pre>' + JSON.stringify(grouped, 0, 4) + '</pre>');
&#13;
&#13;
&#13;

答案 1 :(得分:1)

如果您要分组一组已定义的键,则必须:

  1. 使用map()使用compact()来获取值,以从定义的键集中获取对象集合中的非空值。

  2. 使用zipObject()从定义的键和从第一步获得的值构建结果。

  3. var keys = ["follow", "host", "raid", "substreak", "tip", "subscription"];
    var values = _.map(keys, key => _(data).map(key).compact().value());
    var result = _.zipObject(keys, values);
    

    var data = {
      "20160428": { "follow": 13, "host": 6, "raid": 1, "substreak": 1, "tip": 1 },
      "20160429": { "follow": 15, "host": 21, "raid": 2, "substreak": 4 },
      "20160430": { "follow": 4 },
      "20160501": { "follow": 11, "host": 15, "subscription": 4, "substreak": 5 },
      "20160502": { "follow": 2, "host": 6, "subscription": 1, "substreak": 4 },
      "20160503": { "follow": 2 }
    };
    
    var keys = ["follow", "host", "raid", "substreak", "tip", "subscription"];
    var values = _.map(keys, key => _(data).map(key).compact().value());
    var result = _.zipObject(keys, values);
    
    document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.11.2/lodash.js"></script>

    如果要根据对象集合中的所有键对它们进行分组,则可以:

    1. 通过以下方式获取所有唯一密钥:

      • map()对象集合中的每个数据对象
      • flatten()生成的数组
      • 使用uniq()从展平数组中获取所有唯一键。
    2. 使用第一个示例中的方法来获取值并构建对象。

    3. var keys = _(data).map(_.keys).flatten().uniq().value();
      var values = _.map(keys, key => _(data).map(key).compact().value());
      var result = _.zipObject(keys, values);
      

      var data = {
        "20160428": { "follow": 13, "host": 6, "raid": 1, "substreak": 1, "tip": 1 },
        "20160429": { "follow": 15, "host": 21, "raid": 2, "substreak": 4 },
        "20160430": { "follow": 4 },
        "20160501": { "follow": 11, "host": 15, "subscription": 4, "substreak": 5 },
        "20160502": { "follow": 2, "host": 6, "subscription": 1, "substreak": 4 },
        "20160503": { "follow": 2 }
      };
      
      var keys = _(data).map(_.keys).flatten().uniq().value();
      var values = _.map(keys, key => _(data).map(key).compact().value());
      var result = _.zipObject(keys, values);
      
      document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
      <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.11.2/lodash.js"></script>

答案 2 :(得分:0)

不要在家里试试。

datatable