如何在Node.js中按name分组比较amounts并筛选JSON数据?
在Node.js中实现按名称分组并保留指定条件对象的方法
需求描述
我有如下JSON格式的数据:
[ { "symbol": "USDC", "name": "USD Coin", "decimals": "6", "id": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", "feeTier": "100", "amounts": [2499.769116, 2500.269174] }, { "symbol": "WETH", "name": "Wrapped Ether", "decimals": "18", "id": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", "feeTier": "3000", "amounts": [1.0526261272920125, 1.0590149439506866] }, { "symbol": "USDC", "name": "USD Coin", "decimals": "6", "id": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", "feeTier": "500", "amounts": [2499.591796, 2502.09356] }, { "symbol": "WETH", "name": "Wrapped Ether", "decimals": "18", "id": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", "feeTier": "500", "amounts": [1.0551711392408099, 1.0565026582314214] }, { "symbol": "FRAX", "name": "Frax", "decimals": "18", "id": "0x853d955acef822db058eb8505911ed77f175b99e", "feeTier": "500", "amounts": [2505.1101184400254, 2507.620759133425] } ]
需要将具有相同name的对象分组,比较每组内对象amounts数组的第一个元素,保留该元素值更大的对象,最终期望输出结果如下:
[ { "symbol": "USDC", "name": "USD Coin", "decimals": "6", "id": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", "feeTier": "100", "amounts": [2499.769116, 2500.269174] }, { "symbol": "WETH", "name": "Wrapped Ether", "decimals": "18", "id": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", "feeTier": "3000", "amounts": [1.0526261272920125, 1.0590149439506866] }, { "symbol": "FRAX", "name": "Frax", "decimals": "18", "id": "0x853d955acef822db058eb8505911ed77f175b99e", "feeTier": "500", "amounts": [2505.1101184400254, 2507.620759133425] } ]
请问如何在Node.js中实现这一需求?
实现方案
可以通过Array.prototype.reduce方法完成分组和筛选逻辑,具体步骤如下:
- 用
reduce遍历原始数据,以name为键构建临时对象,存储每个名称对应的最优对象 - 遍历每个对象时,与临时对象中同名称的对象比较
amounts[0]的值,保留数值更大的对象 - 最后将临时对象的取值转换为数组,得到最终结果
完整代码示例
const originalData = [ { "symbol": "USDC", "name": "USD Coin", "decimals": "6", "id": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", "feeTier": "100", "amounts": [2499.769116, 2500.269174] }, { "symbol": "WETH", "name": "Wrapped Ether", "decimals": "18", "id": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", "feeTier": "3000", "amounts": [1.0526261272920125, 1.0590149439506866] }, { "symbol": "USDC", "name": "USD Coin", "decimals": "6", "id": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", "feeTier": "500", "amounts": [2499.591796, 2502.09356] }, { "symbol": "WETH", "name": "Wrapped Ether", "decimals": "18", "id": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", "feeTier": "500", "amounts": [1.0551711392408099, 1.0565026582314214] }, { "symbol": "FRAX", "name": "Frax", "decimals": "18", "id": "0x853d955acef822db058eb8505911ed77f175b99e", "feeTier": "500", "amounts": [2505.1101184400254, 2507.620759133425] } ]; // 核心处理逻辑 const result = Object.values(originalData.reduce((acc, current) => { const currentAmount = current.amounts[0]; // 若当前名称未存入,或当前对象的amounts[0]更大,则更新存储内容 if (!acc[current.name] || currentAmount > acc[current.name].amounts[0]) { acc[current.name] = current; } return acc; }, {})); // 输出格式化后的结果 console.log(JSON.stringify(result, null, 2));
代码说明
reduce方法的初始值为一个空对象,用来临时存储每个name对应的最优对象- 每次遍历判断:如果当前
name未在临时对象中,或者当前对象的amounts[0]数值更大,就替换临时对象中该name对应的内容 - 最后通过
Object.values()将临时对象的所有值提取为数组,得到目标结果
内容的提问来源于stack exchange,提问作者gencero
相关产品推荐
相关产品推荐

