JavaScript中如何统计对象数组内每个路径对应的唯一IP访问量?
方案合理性评价
你现有的实现逻辑是通顺的,能够完成统计每个路径独立IP数量的需求,但存在两个可以优化的点:
- 存在异常风险:
map回调中如果单条日志拆分后path或ip为空,会返回undefined,最终生成的arr数组会包含空项,后续执行arr.map((obj) => obj.path)时会抛出读取undefined属性的报错。 - 性能表现较差:需要多次遍历数组,总时间复杂度为O(n*k),n是总日志条数,k是唯一path的数量,当日志量达到十万级以上时,性能损耗会非常明显。
更优解法
推荐使用单次遍历+嵌套Set的方案,时间复杂度仅为O(n),同时规避了异常风险,实现代码如下:
export const generateUniqueViews = (viewData: string): Map<string, number> => { // 存储每个路径对应的独立IP集合,Set会自动对IP去重 const pathIpMap: Map<string, Set<string>> = new Map(); const lines = viewData.split('\n'); for (const line of lines) { const [path, ip] = line.trim().split(' '); // 跳过格式不符合要求的无效行 if (!path || !ip) continue; if (!pathIpMap.has(path)) { pathIpMap.set(path, new Set()); } pathIpMap.get(path)!.add(ip); } // 转换为路径对应独立IP数量的Map格式返回 const uniqueViewsMap: Map<string, number> = new Map(); for (const [path, ipSet] of pathIpMap) { uniqueViewsMap.set(path, ipSet.size); } return uniqueViewsMap; };
该方案的优势:
- 仅需遍历一次原始日志数组,额外遍历一次唯一路径集合,计算效率远高于多次遍历的实现
- 自动过滤无效行,不会出现空对象属性读取的异常
- 无需额外存储全量的{path, ip}对象数组,内存占用更低
内容的提问来源于stack exchange,提问作者J H
相关产品推荐
相关产品推荐

