使用地图、过滤器等创建自定义过滤对象
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
而不是map
。 map
始终是一对一的。但是你想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”源。以上是关于使用地图、过滤器等创建自定义过滤对象的主要内容,如果未能解决你的问题,请参考以下文章
如何在 vuetify 的数据表中使用“自定义过滤器”道具?或如何创建自定义过滤器以按标题过滤?