Javascript 用Ramdajs变换二维稀疏结果集
我有以下意见:Javascript 用Ramdajs变换二维稀疏结果集,javascript,ramda.js,Javascript,Ramda.js,我有以下意见: 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-
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()实现这一点?(如果纯js解决方案简单,我并不介意)
理想情况下,我希望避免使用[null,null,null]预先填充空月计数并合并到其中。可能直接使用数据转换(转置?)。但我不知道该怎么做,或者这是否可能
在这里摆弄:我得到了一个解决方案,但它需要合并到一个预先填充的月份列表中 我相信这可以简化
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))
在这里拉小提琴:它当然不漂亮,也不是很有效,但我认为这里有一些东西会起作用:
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);
使用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)
这里拉小提琴:我觉得这比我的版本稍微酷一点。我也不知道converge+1当您真的想免费获得积分时,Converge非常有用。Ramda还有一个相关的功能,偶尔会有所帮助。