Професионална програма
Loading...
Reath avatar Reath 188 Точки

Започване на рекурсия от даден index

Разглеждайки начини как динамично да създавам вложени цикли, стигнах до следния отговор в stackoverflow който предлага решение на този проблем чрез рекурсия: https://stackoverflow.com/a/4683760/4138686

 

Това е кода

function callManyTimes(maxIndices, func) {
    doCallManyTimes(maxIndices, func, [], 0);
}

function doCallManyTimes(maxIndices, func, args, index) {
    if (maxIndices.length == 0) {
        func(args);
    } else {
        var rest = maxIndices.slice(1);
        for (args[index] = 0; args[index] < maxIndices[0]; ++args[index]) {
            doCallManyTimes(rest, func, args, index + 1);
        }
    }
}
като той се извиква по този начин:
callManyTimes([2,3,5], doSomething);

Работи страхотно, но в програмата която правя извършвам итерации от сорта на [2000, 2000, 2000] което е огромно число и искам да направя функционалност за запазване на стейта. За да направя това записвам до кои index-и съм стигнал в localStorage, проблема обаче е в случай на рестарт как чрез този код горе да започна рекурсията от дадени index-и? Например не искам да започна от [0, 0, 0] ами от [3, 3, 3]. Представям си да извиквам функцията така:
callManyTimes([2000,2000,2000], doSomething, [942, 800, 0]);
Като новия, трети, параметър да са index-ите от които да започне рекурсията. Какво ли не пробвах, знам че трябва да стартирам for цикъла от дадено число, но не мога да направя сметките. За да ви стане ясно как работи горния код ви съветвам да извикате с console.log, за да видите какво печата и как increment-ва index-ите.
callManyTimes([2,3,5], function(iterators) {
    console.log(iterators);
});

 

Тагове:
0
Module: JS Advanced
Reath avatar Reath 188 Точки

В крайна сметка избрах да използвам тази функция за динамично създаване на вложени цикли:

function everyPermutation(args, fn, startFromIndexes) {
    let indices;

    if (startFromIndexes)
        indices = startFromIndexes;
    else
        indices = args.map(a => a.min);

    for (let j = args.length; j >= 0;) {
        fn.call(null, indices);

        // go through indices from right to left setting them to 0
        for (j = args.length; j--;) {
            // until we find the last index not at max which we increment
            if (indices[j] < args[j].max) {
                ++indices[j];
                break;
            }
            indices[j] = args[j].min;
        }
    }
}

//Normal usage
everyPermutation([
        {min: 0, max: 2},
        {min: 0, max: 2},
        {min: 0, max: 2}],
    function (iterators) {
        console.log(iterators)
    });

//Start from indexes
everyPermutation([
        {min: 0, max: 2},
        {min: 0, max: 2},
        {min: 0, max: 2}],
    function (iterators) {
        console.log(iterators)
    }, [2, 0, 0]);

Освен добавения бонус че си имам min & max параметри с които мога да упомена range за всеки index от пермутацията, благодарение на третия параметър мога да започна от дадени index-и

0