我有以下输入:
var data = [{
month: '2016-01',
city: 'Paris',
count: 6
}, {
month: '2016-01',
city: 'London',
count: 2
}, {
month: '2016-02',
city: 'Paris',
count: 15
}, {
month: '2016-03',
city: 'London',
count: 17
}];
var cityList = ['Paris', 'London'];
数据稀少,因为可能有几个月没有所有城市,没有所有月份的城市。
我想以下列格式转换此哈希:
rowsByCity = [{
city: 'Paris',
counts: [6, 15, null]
}, {
city: 'London',
counts: [2, null, 17]
}];
我如何用Ramdajs(docs)做到这一点? (如果简单的话,我不介意纯粹的js解决方案)
理想情况下,我希望避免使用[null,null,null]预先填充空月计数并合并到其中。也许直接使用数据转换(转置?)。但我不确定该怎么做,或者是否有可能。
答案 0 :(得分:1)
它肯定不漂亮,而且效率也不高,但我认为这些东西会起作用:
const extract = R.converge(
(data, cities, months) => R.map(city => ({
city,
counts: R.map(month => (
R.find(record => record.city === city &&
record.month === month, data) ||
{count: null}
).count, months)
}), cities), [
R.identity,
R.compose(uniq, pluck('city')),
R.compose(uniq, pluck('month'))
]);
extract(data);
答案 1 :(得分:0)
我得到了一个解决方案,但它涉及合并到预先填充的月份列表中。
我确信这可以变得更简单
var months = R.uniq(R.pluck('month', data));
var defaultMonths = R.zipObj(months, R.repeat(null, months.length));
var result = R.mapObjIndexed(
function(counts, city) {
return {
city: city,
counts: R.values(R.merge(
defaultMonths,
R.mapObjIndexed(R.prop('count'), R.indexBy(R.prop('month'), counts))
))
};
},
R.groupBy(R.prop('city'), data))
答案 2 :(得分:0)
使用xprod的另一种解决方案:
var months = R.uniq(R.pluck('month', data));
var cities = R.uniq(R.pluck('city', data));
var result = R.values(R.mapObjIndexed(
(array, city) => {
return {
city: city,
counts: array.map((attrs) => {
return R.find((record) => {
return record.city === attrs[0] && record.month === attrs[1];
}, data)
}).map(R.path(['count']))
}
},
R.groupBy(R.prop(0), R.xprod(cities, months))));
console.log(result)