使用TypeOrm筛选对象数组:保留各分组最大值的唯一对象
如何用TypeOrm处理返回数组,筛选每个分组中score最大值的对象?
问题描述
我现在用TypeOrm从数据库获取了一个对象数组,原始数据如下:
[{"score": 99, "group":"1"},{"score": 90, "group":"2"},{"score":"10", "group":"1"},{"score":"10", "group":"2"}]
需要筛选出每个group中score最大的对象,期望结果:
[{"score": 99, "group":"1"},{"score": 90, "group":"2"}]
解决方案
方案一:数据库层面处理(推荐)
直接通过TypeOrm的QueryBuilder在数据库端完成分组筛选,效率更高,避免全量数据拉取到应用层。假设你的实体类为ScoreRecord,示例代码如下:
import { getRepository } from "typeorm"; import { ScoreRecord } from "./entities/ScoreRecord"; async function getMaxScorePerGroup() { // 第一步:按group分组,获取每个分组的最大score const groupMaxScores = await getRepository(ScoreRecord) .createQueryBuilder("sr") .select(["sr.group", "MAX(sr.score) as maxScore"]) .groupBy("sr.group") .getRawMany(); // 第二步:关联原表,拿到对应分组最高分的完整对象 const finalResult = await getRepository(ScoreRecord) .createQueryBuilder("sr") .where("(sr.group, sr.score) IN (:...pairs)", { pairs: groupMaxScores.map(item => [item.group, item.maxScore]) }) .getMany(); return finalResult; }
如果你的score字段是字符串类型(原始数据存在字符串值),需要先转换为数字再取最大值,修改第一步的查询:
.select(["sr.group", "MAX(CAST(sr.score AS UNSIGNED)) as maxScore"])
方案二:应用层数组处理
如果已经拿到原始数组,可在JS/TS中直接处理:
const rawData = [{"score": 99, "group":"1"},{"score": 90, "group":"2"},{"score":"10", "group":"1"},{"score":"10", "group":"2"}]; // 1. 统一转换score为数字,避免字符串比较错误 const normalizedData = rawData.map(item => ({ ...item, score: Number(item.score) })); // 2. 记录每个分组的最高score const groupMaxMap = new Map(); normalizedData.forEach(item => { const currentMax = groupMaxMap.get(item.group); if (!currentMax || item.score > currentMax) { groupMaxMap.set(item.group, item.score); } }); // 3. 筛选出符合条件的对象 const result = normalizedData.filter(item => item.score === groupMaxMap.get(item.group)); console.log(result);
内容的提问来源于stack exchange,提问作者Anastasiia
相关产品推荐
相关产品推荐

