使用地图,过滤器等创建自定义过滤对象

时间:2017-01-20 15:14:09

标签: javascript data-structures functional-programming iteration reduce

我如何转换这样的集合,我想过滤掉show为false的月份,并使用函数方法创建一个漂亮的干净对象?

    - ./services/api/trial/src:/usr/src/app/src/

这是我试图通过仅使用map,filter,reduce等数组方法创建的结构示例?

    var monthsInYearModel = [
        {'year':'2016', 'months': [
          {name: 'Jan', show: true, num: 0},
          {name: 'Feb', show: false, num: 1},
          {name: 'Mar', show: true, num: 2}
           ...until dec...
       ]}
    ];

这是我的尝试,但我得到的数据太多了

{
   '2016':{
             'jan':0,
             'mar':2,
           ...until dec...
          }
}

here's a plunker

2 个答案:

答案 0 :(得分:0)

尝试

var years = (mnths => ((obj, key, val) => (obj[key] = val, obj))({}, keyCodeYear, mnths) )(
  (arr => arr[0].months.filter(month => month.show).reduce((res, obj) => (res[obj.name] = obj.num, res), {}))(
     monthsInYearModel.filter(obj => obj.year == keyCodeYear)
  )
);

答案 1 :(得分:0)



var monthsInYearModel = [{
  'year' : '2016',
  'months': [
    { name: 'Jan', show: true, num: 0 },
    { name: 'Feb', show: false, num: 1 },
    { name: 'Mar', show: true, num: 2 }
  ]
}, {
  'year': '2017',
  'months': [
    { name: 'Jan', show: false, num: 0 },
    { name: 'Feb', show: false, num: 1 },
    { name: 'Mar', show: false, num: 2 }
  ]
}, {
  'year': '2018',
  'months': [
    { name: 'Jan', show: false, num: 0 },
    { name: 'Feb', show: true, num: 1 },
    { name: 'Mar', show: true, num: 2 }
  ]
}];

// expected
// {
//   '2016': {
//     'jan': 0,
//     'mar': 2
//   }, ...
//


function aggregateYearsIndexWithNonEmptyFilteredMonthLists(collector, yearItem/*, idx, list*/) {
  var
    yearsIndex  = collector.yearsIndex,
    monthList   = yearItem.months.filter(collector.monthCondition);

  if (monthList.length >= 1) {
      yearsIndex[yearItem.year] = monthList.reduce(collector.aggregateMonths, {});
  }
  return collector;
}


var yearsIndex = monthsInYearModel.reduce(aggregateYearsIndexWithNonEmptyFilteredMonthLists, {

  monthCondition  : function(monthItem/*, idx, list*/) {
    return monthItem.show;
  },
  aggregateMonths : function (monthsIndex, monthItem/*, idx, list*/) {
    monthsIndex[monthItem.name.toLowerCase()] = monthItem.num;
    return monthsIndex;
  },
  yearsIndex  : {}

}).yearsIndex;


console.log('yearsIndex : ', yearsIndex);




附加说明 / 已修改

如果OP只想要在某一年内减少数据结构,那么monthsInYearModel只需要相应地进行过滤。其余的仍然由上面提供的解决方案覆盖...

var yearsIndex = monthsInYearModel.filter(function (yearItem) {

    return (Number(yearItem.year) == 2016);

}).reduce(aggregateYearsIndexWithNonEmptyFilteredMonthLists, {

  monthCondition  : function(monthItem/*, idx, list*/) {
    return monthItem.show;
  },
  aggregateMonths : function (monthsIndex, monthItem/*, idx, list*/) {
    monthsIndex[monthItem.name.toLowerCase()] = monthItem.num;
    return monthsIndex;
  },
  yearsIndex  : {}

}).yearsIndex;


console.log('yearsIndex : ', yearsIndex);