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

Posted

技术标签:

【中文标题】使用地图、过滤器等创建自定义过滤对象【英文标题】: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 【参考方案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”源。

以上是关于使用地图、过滤器等创建自定义过滤对象的主要内容,如果未能解决你的问题,请参考以下文章

过滤自定义对象的 NSMutable 数组

如何在 vuetify 的数据表中使用“自定义过滤器”道具?或如何创建自定义过滤器以按标题过滤?

iOS QuickBlox SDK 按用户 ID 过滤自定义对象

如何在 C++ 应用程序中使用自定义捕获源过滤器?

Django 自定义模板标签和过滤器

ng 自定义过滤器的创建和使用