【问题标题】:Create a custom filtered object using map, filter etc使用地图、过滤器等创建自定义过滤对象
【发布时间】:2017-06-05 15:06:40
【问题描述】:

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

    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...
       ]}
    ];

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

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

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

     var keyCodeYear = '2016'

     var years = monthsInYearModel
     .filter( obj => obj.year == keyCodeYear )
     .map( obj => obj.months.filter(month => month.show) );

{
   [
   '2016':[
            {name:'jan', num:0 },
            {name:'mar', num:2 }
            ...until dec...
          ]
   ]
}

here's a plunker

【问题讨论】:

  • 您需要reduce 而不是mapmap 始终是一对一的。但是你想reduce在每一层都变成一个对象。
  • 抱歉输出到控制台:S

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


【解决方案1】:

试试

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)
  )
);

【讨论】:

    【解决方案2】:

    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);
    

    【讨论】:

    • @Mangopop ...除了上面提供的解决方案之外,我还更新了您的“plunker”源。
    猜你喜欢
    • 2019-04-04
    • 1970-01-01
    • 1970-01-01
    • 2016-06-29
    • 2019-10-22
    • 2015-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多