在 JavaScript 中使用 Map、Reduce 和 Filter 从嵌套数组打印

最终目的是为以下数组中的每个名称获取一个。(类似于下面代码片段底部注释掉的行)


如果有同名,则只取数量最多的,如果有重复,则只取版本较高的。


我尝试使用map、reduce的组合。请帮我解决这个问题。


//Original array

var arr = [

  {'name': 'b', 'version': '103', 'count': 10}, 

  {'name': 'a', 'version': '0.1b', 'count': 73}, 

  {'name': 'b', 'version': '109', 'count': 67}, 

  {'name': 'a', 'version': '1.0.3', 'count': 100}, 

  {'name': 'a', 'version': '2.1.0', 'count': 100}, 

  {'name': 'c', 'version': 'a103', 'count': 30}, 

  {'name': 'c', 'version': 'a111', 'count': 100}

];


//expected console output

// { name: 'a', version: '2.1.0', count: 100 }

// { name: 'b', version: '109', count: 67 }

// { name: 'c', version: 'a111', count: 100 }

首先,作为该过程的“一部分”,我尝试从数组中获取“a”。


var filteredArr = arr.filter(item => item.name === 'a');


var m = Math.max(...(filteredArr.map(({count}) => count))),

  maxes = arr.map(({count}) => count).reduce((p,c,i,a) => c ==  m ? p.concat(i) : p,[]);

console.log(maxes);

我期望从上面得到 [3, 4],但它打印出 [3, 4, 6]。


=====


附加问题:


我该如何处理这另一个原始的预期。


//Another original array.

var arr2 = [ 

  { name: 'a', version: '0.1', count: 1 },

  { name: 'b', version: '216', count: 1 },

  { name: 'b', version: '209', count: 1 },

  { name: 'b', version: '216', count: 1 },

  { name: 'b', version: '216', count: 1 },

  { name: 'b', version: '213', count: 1 },

  { name: 'b', version: '213', count: 1 },

  { name: 'b', version: '209', count: 1 },

  { name: 'b', version: '216', count: 1 },

  { name: 'b', version: '216', count: 1 }

];


//expected output

// { name: 'a', version: '0.1', count: 1 },

// { name: 'b', version: '216', count: 5 },

// { name: 'b', version: '209', count: 2 },

// { name: 'b', version: '213', count: 2 }


哈士奇WWW
浏览 65回答 2
2回答

弑天下

您可以Array#reduce与对象一起使用来存储每个名称的对象。var arr = [&nbsp; {'name': 'b', 'version': '103', 'count': 10},&nbsp;&nbsp; {'name': 'a', 'version': '0.1b', 'count': 73},&nbsp;&nbsp; {'name': 'b', 'version': '109', 'count': 67},&nbsp;&nbsp; {'name': 'a', 'version': '1.0.3', 'count': 100},&nbsp;&nbsp; {'name': 'a', 'version': '2.1.0', 'count': 100},&nbsp;&nbsp; {'name': 'c', 'version': 'a103', 'count': 30},&nbsp;&nbsp; {'name': 'c', 'version': 'a111', 'count': 100}];const res = Object.values(arr.reduce((acc,{name, version, count})=>{&nbsp; if(!acc[name] || acc[name] &&&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (acc[name].count < count&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|| acc[name].count === count && acc[name].version < version)){&nbsp; &nbsp; acc[name] = {name, version, count};&nbsp; }&nbsp; return acc;}, {}));console.log(res);

幕布斯6054654

看来您在第二种情况下想要做的是聚合count具有相同name和的条目的属性version(类似于数据库中的COUNT+GROUP BY查询SQL)。在这种情况下,您可以首先在第一级计算dictionary_res索引,然后在第二级计算索引:nameversiondictionary_res = arr2.reduce((acc, { name, version, count }) => {&nbsp; if (!acc[name] || (acc[name] && !acc[name][version])) {&nbsp; &nbsp; acc[name] = acc[name] || {}&nbsp; &nbsp; acc[name][version] = { count: count }&nbsp; } else {&nbsp; &nbsp; acc[name][version]['count'] = acc[name][version]['count'] + count&nbsp; }&nbsp; return acc}, {})dictionary_res产生一个非常接近您想要的值:{&nbsp; a: { '0.1': { count: 1 } },&nbsp; b:&nbsp; { '209': { count: 2 }, '213': { count: 2 }, '216': { count: 5 } }}但是,您仍然需要将其转换为数组才能完全实现您想要的:array_res = Object.keys(dictionary_res).reduce((acc, name) => {&nbsp; Object.keys(dictionary_res[name]).forEach((version) => (&nbsp; &nbsp; acc.push({ name, version, count: dictionary_res[name][version]['count'] })&nbsp; ))&nbsp; return acc}, [])array_res现在产生预期值:[ { name: 'a', version: '0.1', count: 1 },&nbsp; { name: 'b', version: '209', count: 2 },&nbsp; { name: 'b', version: '213', count: 2 },&nbsp; { name: 'b', version: '216', count: 5 } ]
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript