使用Ramdajs转换二维稀疏结果集

时间:2016-09-02 17:14:59

标签: 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-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]预先填充空月计数并合并到其中。也许直接使用数据转换(转置?)。但我不确定该怎么做,或者是否有可能。

在这里小提琴:https://jsfiddle.net/dtr0js55/

3 个答案:

答案 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))

在这里小提琴:https://jsfiddle.net/s141r74y/

答案 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)

在这里小提琴:https://jsfiddle.net/44ysat8d/