编辑代码

let getIndex = (_list, target) => {
    //大于的 直接过滤掉 最后的结果将在以下组合中产出 转成 key,index 的形式
    let xiaoyu = _list.map((key, index) => { return { key, index } }).filter(m=> m.key <= target);
    //找到所有的组合 [[0],[0,1],[0,1,2],[1],[1,2]...]
    let getzuhe = (arr) => { 
        let _getzhe = (_arr) => { 
            if (_arr.length == 1) return _arr;
            let arr1 = _getzhe(_arr.slice(1));
            let map1 = arr1.map(m => `${_arr[0]},${m}`);
            let map2 = _getzhe(_arr.slice(1));
            let map3 = [_arr[0]];
            return map1.concat(map2, map3);
        }
        let map = _getzhe(Array.from({ length: arr.length }, (_, i) => i))
                         .map(m=>(m+'').split(',').map(m=>parseInt(m)));
        return map.map(m => m.map(i => arr[i]));
    }
    let zuhes = getzuhe(xiaoyu);
    console.log('有效长度>',xiaoyu.length);
    console.log('组合数>',zuhes.length);
    //计算组合的值 大于的去掉,找最接近的
    let jiejin = [];
    zuhes.forEach(zuhe => { 
        let he = zuhe.map(m=>m.key).reduce((t, v)  => t+v);//得到这个组合的值之和
        let indexs = zuhe.map(m=>m.index).reduce((t, v) => t+v);//得到这个组合的角标之和
        if (he <= target) {
            //只保留大于等于当前的
            jiejin = jiejin.filter(m => m.he >= he); 
            //如果都等于当前的和,可以加入 否则不加
            if (jiejin.length == 0 || jiejin.some(m => he >= m.he)) {
                jiejin.push({ zuhe, he, indexs, length: zuhe.length });
            }
        }
    })
    //如果是多个,找组合最小的 角标集合
    return jiejin.filter(m => m.indexs == Math.min.apply(null, jiejin.map(m => m.indexs)));
}
let list = [1000, 2000, 500, 1500, 3456, 57, 67, 345, 2346456, 8, 4556, 78, 1267, 68689, 43];
let jieguo = getIndex(list, 3235);
console.log('计算结果>',JSON.stringify(jieguo));
console.log('最接近的组合是 >',jieguo.map(m=>m.zuhe.map((m=>m.key))));
console.log('最接近的值是 >',jieguo.map(m=>m.zuhe.map((m=>m.key)))[0].reduce((t,v)=>t+v,0));
console.log('最接近的角标是 >',jieguo.map(m=>m.zuhe.map((m=>m.index))));