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
qwertyto avatar qwertyto 15 Точки

За какво ти е да извикваш функция 8 милиарда пъти в динамично генерирани цикли?

0
TeodorStefanovPld avatar TeodorStefanovPld 1274 Точки

и на мен ми се изгуби малко идеята на колегата :Д

callManyTimes([2000,2000,2000], doSomething, [942, 800, 0]); иначе това не ми се струва ок,по-скоро

callManyTimes([2000,2000,2000], doSomething,callManyTimes [iterators]) като по някакъв начин ще трябва да си записваш индексите които ти трябват и да ги подаваш просто,но малко се изгубих защо искаш да въртиш рекурсия в for цикъл и тои да се вика сам на определени индекси това дори само като го написах и звучи сттранно

0
Reath avatar Reath 188 Точки

Client side bruteforce :)

Знам, че javascript не е най-оптималните езици за постигане на целта, но поради някакви съображения съм написал програмата именно на js. Извинявам се ако съм описал странно проблема си, ще опитам отново.

 

Имам рекурсия благодарение на която мога да направя bruteforce с едно неизвестно, или с две, или с колкото си искам неизвестни. Единия for цикъл е просто инструмент с който рекурсивната функция си борави за да успее да направи имитацията на вложените цикли. Когато извикваме тази функция с параметъра maxIndices настроен на [5] ще ни викне callback функцията веднъж с 0, после с 1,2,3,4.. Ако извикаме рекурсията с параметър [3,3] ще започне първо от 0,1; 0,2; 1,0; 1,1; 1,2; 2,0; 2,1... Въпроса ми е ако вече съм минал през 0,1; 0,2, но програмата ми е била затворена, как при следващото стартиране да стартирам рекурсията директно от 1,0 и тя да продължи към 1,1; 1,2; 2,1...

 

Един вид искам същата тази рекурсивна функция да мога да я викам, но да мога да я настроя да не започва от 0леви index-и

0
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
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.