JSON数组字段如何累加并排序?

category属性相同,value字段进行累加,然后按照累加结果的从大到小进行排序
例如当 category 等于 的时候 那么 A,B,C 的 value 相加,最终按照相加结果的由大到小进行排序,最终顺序为 土、火、金;

[
  {
    "name": "A",
    "category": "火",
    "value": 9.5
  },
  {
    "name": "B",
    "category": "火",
    "value": 7.5
  },
  {
    "name": "C",
    "category": "火",
    "value": 6.15
  },
  {
    "name": "A",
    "category": "土",
    "value": 10.5
  },
  {
    "name": "B",
    "category": "土",
    "value": 12.5
  },
  {
    "name": "C",
    "category": "土",
    "value": 15.02
  },
  {
    "name": "A",
    "category": "金",
    "value": 0.75
  },
  {
    "name": "B",
    "category": "金",
    "value": 0.3
  },
  {
    "name": "C",
    "category": "金",
    "value": 0.15
  }
]


期望结果

[
  {
    "name": "A",
    "category": "土",
    "value": 10.5
  },
  {
    "name": "B",
    "category": "土",
    "value": 12.5
  },
  {
    "name": "C",
    "category": "土",
    "value": 15.02
  },
  {
    "name": "A",
    "category": "火",
    "value": 9.5
  },
  {
    "name": "B",
    "category": "火",
    "value": 7.5
  },
  {
    "name": "C",
    "category": "火",
    "value": 6.15
  },
  {
    "name": "A",
    "category": "金",
    "value": 0.75
  },
  {
    "name": "B",
    "category": "金",
    "value": 0.3
  },
  {
    "name": "C",
    "category": "金",
    "value": 0.15
  }
]

阅读 2.2k
3 个回答
acc = data.reduce((o, {category: c, value: v}) => {o[c] = (o[c] ?? 0) + v; return o}, {});
data.sort((a, b) => acc[b.category] - acc[a.category]);

这是一个用 Lodash 实现的答案,比 @无名 那个原生实现的效率会低一些。不过该答案可以体现解决这个问题的一个基本思路。

var result = _(data)            // 使用 Lodash 的 Lazy 计算来处理
    .groupBy("category")        // 按 category 分组
    .values()                   // 取分组后的“值”,即每组元素(数组)
    .map(its => ({ its, sum: _.sumBy(its, "value") }))  // 合计并产生一个辅助对象 { sum, its }
    .sortBy("sum")              // 按 sum 排序(从小到大)
    .reverse()                  // 逆序(从大到小)
    .flatMap(it => it.its)      // 从辅助对象中抽取实际的数据(数组 its),并展平
    .value();                   // 触发计算并得到结果
let arr = list.reduce((s, v) => {
  let index = s.findIndex(it => v.category === it.category)
  index === -1 ? s.push({...v}) : s[index].value += v.value
  return s
}, [])
let obj = Object.fromEntries(arr.map(({category, value}) => [category, value]))
list.sort((s, v)=> obj[v.category] - obj[s.category])
console.log(list)
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题