Генераторы es6 декартовы

У меня есть функция для вычисления декартовых комбинаций:

function cartes1(a, b, c) {
    let arr = []
    for (let i1 of a) {
        for (let i2 of b) {
            for (let i3 of c) {
                arr.push([i1, i2, i3])
            }
        }
    }
    return arr;
}

Я хочу преобразовать его в генератор, который будет останавливаться при необходимости, поэтому сделал это:

function* cartes(a, b, c) {
    for (let i1 of a) {
        for (let i2 of b) {
            for (let i3 of c) {
                yield [i1, i2, i3]
            }
        }
    }
}

Код в основном тот же, но второй возвращает неверные результаты.

cartes1([1,2,3],[1,2,3],[1,2,3]) // correct
cartes([1,2,3],[1,2,3],[1,2,3])

Генератор возвращает это:

[[ 1, 1, 1 ]
[ 1, 1, 2 ]
[ 1, 1, 3 ]]

Функция генератора вызывается с помощью

cartes(range(1)(3)(1), range(1)(3)(1), range(1)(3)(1))
const range = from => to => function*(step=1) {
    for(let i=from;i<=to;i+=step) {
        yield i
    }
}

Я что-то упускаю ?

Спасибо

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
0
65
1

Ответы 1

Что вы сделали, так это использовали три генератора, но если они закончены, вы не можете их перемотать.

Чтобы предотвратить это, вы можете вернуть jzs закрытие над собранным значением и вызвать генератор в первый раз в цикле for.

Generator#next возвращает done, если gerator достиг последнего return, либо непосредственно с помощью этого оператора, либо в конце функции.

function* утверждает:

The next() method returns an object with a value property containing the yielded value and a done property which indicates whether the generator has yielded its last value as a boolean. Calling the next() method with an argument will resume the generator function execution, replacing the yield expression where execution was paused with the argument from next().

A return statement in a generator, when executed, will make the generator finished (i.e the done property of the object returned by it will be set to true). If a value is returned, it will be set as the value property of the object returned by the generator.

Much like a return statement, an error thrown inside the generator will make the generator finished -- unless caught within the generator's body.

When a generator is finished, subsequent next calls will not execute any of that generator's code, they will just return an object of this form: {value: undefined, done: true}. [emph by ns]

function* cartes(a, b, c) {
    for (let i1 of a()) {
        for (let i2 of b()) {
            for (let i3 of c()) {
                yield [i1, i2, i3];
            }
        }
    }
}

const range = from => to => (step = 1) => function* () {
    for (let i = from; i <= to; i += step) {
        yield i;
    }
};

for (let v of cartes(range(1)(3)(1), range(1)(3)(1), range(1)(3)(1))) {
    console.info(v);
}

Это преобразует их в массив. Я не хочу этого. Я хочу быть генератором. Я уже использую for of, но почему он останавливается после первых итераций первого массива

user2693928 10.10.2018 08:24

Спасибо, но почему генератор доработан. for (let if1 of a) - почему возвращается только первая комбинация, разве нет смысла перебирать все элементы первого элемента

user2693928 10.10.2018 08:43
i1 не закончен, это последний i3. которые предотвращают получение значений для i2, потому что, запустив самый внутренний цикл for, вы больше не получите никакого значения. генераторы сохраняют свою позицию и, если закончили ... она останавливается.
Nina Scholz 10.10.2018 08:53

Другие вопросы по теме