У меня есть функция для вычисления декартовых комбинаций:
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
}
}
Я что-то упускаю ?
Спасибо



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Что вы сделали, так это использовали три генератора, но если они закончены, вы не можете их перемотать.
Чтобы предотвратить это, вы можете вернуть jzs закрытие над собранным значением и вызвать генератор в первый раз в цикле for.
Generator#next возвращает done, если gerator достиг последнего return, либо непосредственно с помощью этого оператора, либо в конце функции.
The
next()method returns an object with avalueproperty containing the yielded value and adoneproperty which indicates whether the generator has yielded its last value as a boolean. Calling thenext()method with an argument will resume the generator function execution, replacing the yield expression where execution was paused with the argument fromnext().A
returnstatement in a generator, when executed, will make the generator finished (i.e thedoneproperty of the object returned by it will be set to true). If a value is returned, it will be set as thevalueproperty of the object returned by the generator.Much like a
returnstatement, an error thrown inside the generator will make the generator finished -- unless caught within the generator's body.When a generator is finished, subsequent
nextcalls 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 (let if1 of a) - почему возвращается только первая комбинация, разве нет смысла перебирать все элементы первого элемента
i1 не закончен, это последний i3. которые предотвращают получение значений для i2, потому что, запустив самый внутренний цикл for, вы больше не получите никакого значения. генераторы сохраняют свою позицию и, если закончили ... она останавливается.
Это преобразует их в массив. Я не хочу этого. Я хочу быть генератором. Я уже использую for of, но почему он останавливается после первых итераций первого массива