如何在Lodash分组后的数组对象中添加按值排序的Top2水果列表?
解决按颜色分组并添加Top2水果列表的问题
需求背景
我手里有一组包含水果信息的数组,需要按颜色做分组统计:既要算出每个颜色组的总Value,还要给每个组加上Top2列表——也就是该颜色下按Value总和排序的前2种水果,排序顺序必须是从高到低。
原始数据
var myArray = [ {Color:"red", Fruit:"apple", Country:"us", Value:1}, {Color:"red", Fruit:"cherry", Country:"us", Value:1}, {Color:"red", Fruit:"apple", Country:"italy", Value:1}, {Color:"red", Fruit:"apple", Country:"italy", Value:2}, {Color:"red", Fruit:"strawberry", Country:"italy", Value:2}, {Color:"red", Fruit:"cherry", Country:"italy", Value:1}, {Color:"yellow", Fruit:"banana", Country:"us", Value:1}, {Color:"yellow", Fruit:"banana", Country:"italy", Value:1}, {Color:"yellow", Fruit:"pineapple", Country:"italy", Value:5}, {Color:"yellow", Fruit:"mango", Country:"italy", Value:3}, ];
初始尝试代码
一开始我用Lodash实现了按颜色分组和总Value计算,但还没搞定Top2列表的需求:
var groupColor = _(_.where(myArray, { Country: "italy", })).groupBy("Color"); var myNewArray=_(groupColor).map(function(g, key) { return { Color: key || 0, Total: _(g).reduce(function(m, x) { return m + x.Value; }, 0), }; });
期望结果
最终想要得到的数组格式如下:
var myNewArray = [ { Color: "red", Total: 6, top2:"apple, strawberry" }, { Color: "yellow", Total: 9, top2:"pineapple,mango" }, ];
最终解决代码
经过几次调整,我写出了能满足需求的完整代码:
// 先筛选出意大利地区的水果数据 var ArraySelectCountry = _(_.where(myArray, {Country: "italy"})); // 按「颜色+水果」分组,计算每种水果的总Value var ObjectsGrouped = _(ArraySelectCountry).chain() .groupBy(function (itm) { return itm.Color + itm.Fruit ; }) .map(function (itm, key) { var sum = _(itm).chain() .pluck("Value") .reduce(function (memo, value) { return memo + Number(value); }, 0.0) .value(); return _.object(["Color", "Fruit", "Value"], [itm[0].Color, itm[0].Fruit, sum]) }) .value(); // 按总Value降序排序,确保高价值水果排在前面 ObjectsGrouped= _.sortBy(ObjectsGrouped, function(o) { return o.Value; }).reverse(); // 再次按颜色分组,整理成颜色维度的集合 var ObjectsGroupedByColor = _(ObjectsGrouped).groupBy('Color'); // 生成最终结果:计算总Value + 提取前2种水果作为top2 var myNewArray = _(ObjectsGroupedByColor).map(function(g, key) { // 取每组前2个水果,拼接成字符串 const top2Fruits = g.slice(0,2).map(item => item.Fruit).join(', '); return { Color: key, Total: _(g).reduce(function(m,x) { return m + x.Value; }, 0), top2: top2Fruits }; });
关键步骤拆解
- 缩小数据范围:先筛选出目标国家(意大利)的数据,减少后续计算量;
- 合并同水果数据:按
Color+Fruit分组,把同一颜色同一水果的Value求和,得到每种水果的总价值; - 排序优先级:按总Value降序排序,保证高价值水果排在最前面;
- 最终分组整理:按颜色分组后,直接取每组前2个水果生成
top2字符串,同时计算组内总Value。
内容的提问来源于stack exchange,提问作者observatoire
相关产品推荐
相关产品推荐

