JavaScript递归函数保留原数组获取原始索引的代码修改咨询
解决方案
方案1:新增可选参数透传原始数组
给递归函数增加第四个可选参数存储原始数组,仅首次调用时初始化,递归时直接透传即可:
function subsetSum(numbers, target, partial, originalList) { var s, n, remaining; // 首次调用时如果没传originalList,默认用当前传入的完整数组作为原始数组 originalList = originalList || numbers; partial = partial || []; // sum partial s = partial.reduce(function (a, b) { return Math.round((a + b)*100)/100; }, 0); // check if the partial sum is equals to target if (s === target) { console.log(originalList); partial.forEach(function(findIndex){ console.log(findIndex, 'is at position ', originalList.indexOf(findIndex)); }); } for (var i = 0; i < numbers.length; i++) { n = numbers[i]; remaining = numbers.slice(i + 1); // 递归调用时透传originalList subsetSum(remaining, target, partial.concat([n]), originalList); } } // 调用方式,不需要额外传原始数组,默认用第一个参数作为原始数组 subsetSum([3,9,8,4,5.5,7,10.07],15.57); // 也可以主动指定原始数组,比如你要基于外部的其他数组获取索引 const myCustomList = [2,3,5,7,11]; subsetSum(myCustomList, 10, undefined, myCustomList);
方案2:用闭包封装避免递归传参
如果不想每次递归都透传参数,可以用外层函数把原始数组存在闭包里,代码更简洁:
function createSubsetSumSolver(originalList) { // 内部递归函数直接使用闭包中的originalList,不需要额外传参 function subsetSum(numbers, target, partial) { var s, n, remaining; partial = partial || []; // sum partial s = partial.reduce(function (a, b) { return Math.round((a + b)*100)/100; }, 0); // check if the partial sum is equals to target if (s === target) { console.log(originalList); partial.forEach(function(findIndex){ console.log(findIndex, 'is at position ', originalList.indexOf(findIndex)); }); } for (var i = 0; i < numbers.length; i++) { n = numbers[i]; remaining = numbers.slice(i + 1); subsetSum(remaining, target, partial.concat([n])); } } // 返回调用入口,只需要传入目标和即可触发计算 return function(target) { return subsetSum(originalList, target); } } // 调用方式 const solveSubsetSum = createSubsetSumSolver([3,9,8,4,5.5,7,10.07]); solveSubsetSum(15.57);
注意事项
如果你的原始数组中存在重复数值,Array.indexOf()只会返回第一个匹配项的索引,会导致索引结果不准确。如果需要完全准确的原始索引,建议初始时把数值和索引绑定处理:
// 把原数组转成带索引的对象 const originalList = [3,9,8,4,5.5,7,10.07]; const indexedList = originalList.map((val, idx) => ({ value: val, index: idx })); // 后续计算和的时候取value属性,匹配到结果后直接取index属性即可得到准确原始索引
内容的提问来源于stack exchange,提问作者lin ede
相关产品推荐
相关产品推荐

