如何将API返回的JSON数据处理为react-heatmap-grid所需的补0数组
问题原因
你原代码的逻辑错误出在三重循环的设计:对每一组aisle + zone组合,都完整遍历了一次全部的mappings数组,所以每一组组合都会对应7次判断(因为mappings共7条数据),加了else之后就会每组组合最多push1个有效值+6个0,最终总长度就是4货道3区域7条映射=84,自然不符合要求。
解决思路
- 先把现有映射转成快速查找的哈希结构,避免重复遍历映射表
- 遍历所有货道+区域的组合时,直接查哈希表,存在就取对应数量,不存在就补0,每组组合只push1个值到数组里
- 逻辑计算不要写在JSX的插值块中,放在组件渲染逻辑部分更易维护
修正后代码
import React, { useMemo } from 'react'; import HeatMap from "react-heatmap-grid"; function VolumeHeatmap(props){ const mappings = [ {"aisle":"A1", "zone":"AAA", "quantity":"23"}, {"aisle":"A1", "zone":"AAB", "quantity":"12"}, {"aisle":"A1", "zone":"AAC", "quantity":"53"}, {"aisle":"A2", "zone":"AAA", "quantity":"64"}, {"aisle":"A2", "zone":"AAC", "quantity":"41"}, {"aisle":"A3", "zone":"AAB", "quantity":"5"}, {"aisle":"A4", "zone":"AAC", "quantity":"9"} ] // 用useMemo缓存计算结果,避免重复渲染重复计算 const { data, aisles, zones } = useMemo(() => { // 1. 去重得到所有货道、区域 const aisles = [...new Set(mappings.map(item => item.aisle))]; const zones = [...new Set(mappings.map(item => item.zone))]; // 2. 构建查找表,key为货道+区域的组合标识 const lookupMap = new Map(); mappings.forEach(item => { lookupMap.set(`${item.aisle}:${item.zone}`, Number(item.quantity)); }); // 3. 遍历所有组合生成最终数组 const data = []; aisles.forEach(aisle => { zones.forEach(zone => { // 存在就取数量,不存在补0 data.push(lookupMap.get(`${aisle}:${zone}`) || 0); }) }) return { data, aisles, zones }; }, [mappings]); // 测试输出结果为 [23, 12, 53, 64, 0, 41, 0, 5, 0, 0, 0, 9] 符合预期 console.log(data); return ( <div> {/* 后续渲染HeatMap的逻辑可以直接用aisles、zones、data三个变量 */} </div> ) } export default VolumeHeatmap;
代码说明
- 用
Set做去重比手写的去重方法性能更好,写法更简洁 - 用
Map做查找表,每对组合只需要一次O(1)的查找,比原来三重循环的O(nmk)时间复杂度低很多,数据量大的时候优势更明显 - 用
useMemo缓存计算结果,只有mappings变化的时候才会重新计算,避免不必要的性能消耗
内容的提问来源于stack exchange,提问作者lekocast
相关产品推荐
相关产品推荐

