使用Object.keys(arr).reduce()返回undefined问题求助
问题分析与解决思路
先把你的代码和问题梳理清楚:
你通过以下代码创建了价格区间对象:
var val = $(this).val(); var type = " " + $("#backing").val() + " "; var arr = $.extend({}, comb_arr[type]);
得到的arr结构为:
var arr = {"1-4 ": "$10.10 ", "5-9 ": "$8.34 ", "10-24 ": "$7.71 ", "25-49 ": "$7.21 "}
但运行reduce代码时输出undefined:
var price = Object.keys(arr).reduce((a, c) => { var s = c.trim(); if(/\d+\-\d+/.test(s)){ var range = s.split("-"); if(val >= parseInt(range[0]) && val <= parseInt(range[1])){ a = comb_arr[c]; } }else{ s = s.replace(/\D/g, ""); if(val >= s){ a = comb_arr[c]; } } return a; },0);
核心问题排查与修复方案
错误1:引用了错误的对象
你在找到匹配区间后赋值a = comb_arr[c],但comb_arr的键是type(比如带空格的类型字符串),而c是arr里的区间键(比如"1-4 "),comb_arr中根本不存在c这个键,自然返回undefined。正确的做法是引用当前的arr对象:a = arr[c]; // 替换原来的comb_arr[c]错误2:字符串与数字的比较问题
val是$(this).val()获取的字符串值,直接用字符串和数字比较会导致逻辑错误(比如字符串"10"和数字5比较时,会按ASCII码判断,结果是false)。需要先把val转换为数字:var numVal = parseInt(val, 10); // 提前转换为数字,第二个参数10指定十进制,避免意外进制问题 // 后续比较都用numVal if(numVal >= parseInt(range[0], 10) && numVal <= parseInt(range[1], 10)){优化:提前终止不必要的循环
因为价格区间是互斥的,找到匹配的区间后可以直接返回结果,不用继续遍历剩余键。虽然reduce不能直接break,但可以利用返回值跳过后续处理;或者改用find方法更直观:var numVal = parseInt(val, 10); var matchedKey = Object.keys(arr).find(key => { var s = key.trim(); if(/\d+\-\d+/.test(s)){ const [min, max] = s.split("-").map(Number); return numVal >= min && numVal <= max; } else { const min = Number(s.replace(/\D/g, "")); return numVal >= min; } }); var price = matchedKey ? arr[matchedKey] : 0; // 没找到匹配返回0,和原初始值一致额外注意:键的空格处理
你的arr的键都带有末尾空格(比如"1-4 "),虽然trim()后能正确匹配正则,但在引用arr[c]时要确保用的是原键(带空格),这部分你当前的代码是对的,因为c就是原键。
修复后的完整代码示例
var val = $(this).val(); var type = " " + $("#backing").val() + " "; var arr = $.extend({}, comb_arr[type]); var numVal = parseInt(val, 10); var price = Object.keys(arr).reduce((a, c) => { if (a !== 0) return a; // 如果已经找到匹配,直接返回,跳过后续处理 var s = c.trim(); if(/\d+\-\d+/.test(s)){ var range = s.split("-").map(num => parseInt(num, 10)); if(numVal >= range[0] && numVal <= range[1]){ a = arr[c]; } }else{ s = s.replace(/\D/g, ""); var min = parseInt(s, 10); if(numVal >= min){ a = arr[c]; } } return a; }, 0);
内容的提问来源于stack exchange,提问作者Top-Bot
相关产品推荐
相关产品推荐

