使用动态键对嵌套对象进行分组(使用 Lodash)
Grouping Nested Objects with Dynamic Keys (Using 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
次,但此时我无法更改架构。
您可以使用普通 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>');
不要在家里尝试这个。
var fields = {
follow: 0,
host: 0,
raid: 0,
substreak: 0,
tip: 0,
subscription: 0
};
_(data)
.values()
.map(x => _.assign({}, fields, x))
.map(_.toPairs)
.flatten()
.groupBy(0)
.mapValues(x => _.map(x, 1))
.value();
如果您有一组已定义的要分组的键,那么您必须:
使用 zipObject() 从第一步获得的定义键和值构建结果。
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>
如果您想根据对象集合中存在的所有键对它们进行分组,那么您可以:
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>
我正在查询 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
次,但此时我无法更改架构。
您可以使用普通 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>');
不要在家里尝试这个。
var fields = {
follow: 0,
host: 0,
raid: 0,
substreak: 0,
tip: 0,
subscription: 0
};
_(data)
.values()
.map(x => _.assign({}, fields, x))
.map(_.toPairs)
.flatten()
.groupBy(0)
.mapValues(x => _.map(x, 1))
.value();
如果您有一组已定义的要分组的键,那么您必须:
使用 zipObject() 从第一步获得的定义键和值构建结果。
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>
如果您想根据对象集合中存在的所有键对它们进行分组,那么您可以:
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>