为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

哈士奇WWW 2023-11-11 21:43:56
最终目的是为以下数组中的每个名称获取一个。(类似于下面代码片段底部注释掉的行)如果有同名,则只取数量最多的,如果有重复,则只取版本较高的。我尝试使用map、reduce的组合。请帮我解决这个问题。//Original arrayvar 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 }
查看完整描述

2 回答

?
弑天下

TA贡献1818条经验 获得超7个赞

您可以Array#reduce与对象一起使用来存储每个名称的对象。


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}

];

const res = Object.values(arr.reduce((acc,{name, version, count})=>{

  if(!acc[name] || acc[name] && 

          (acc[name].count < count 

           || acc[name].count === count && acc[name].version < version)){

    acc[name] = {name, version, count};

  }

  return acc;

}, {}));

console.log(res);


查看完整回答
反对 回复 2023-11-11
?
幕布斯6054654

TA贡献1876条经验 获得超7个赞

看来您在第二种情况下想要做的是聚合count具有相同name和的条目的属性version(类似于数据库中的COUNT+GROUP BY查询SQL)。


在这种情况下,您可以首先在第一级计算dictionary_res索引,然后在第二级计算索引:nameversion


dictionary_res = arr2.reduce((acc, { name, version, count }) => {

  if (!acc[name] || (acc[name] && !acc[name][version])) {

    acc[name] = acc[name] || {}

    acc[name][version] = { count: count }

  } else {

    acc[name][version]['count'] = acc[name][version]['count'] + count

  }

  return acc

}, {})

dictionary_res产生一个非常接近您想要的值:


{

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

  b:

  { '209': { count: 2 }, '213': { count: 2 }, '216': { count: 5 } }

}

但是,您仍然需要将其转换为数组才能完全实现您想要的:


array_res = Object.keys(dictionary_res).reduce((acc, name) => {

  Object.keys(dictionary_res[name]).forEach((version) => (

    acc.push({ name, version, count: dictionary_res[name][version]['count'] })

  ))

  return acc

}, [])

array_res现在产生预期值:


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

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

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

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


查看完整回答
反对 回复 2023-11-11
  • 2 回答
  • 0 关注
  • 62 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信