Skip to content

Instantly share code, notes, and snippets.

@arvigeus
Created May 2, 2019 14:24
Show Gist options
  • Save arvigeus/c3763e5a3f6e7fc079937b9e2413519f to your computer and use it in GitHub Desktop.
Save arvigeus/c3763e5a3f6e7fc079937b9e2413519f to your computer and use it in GitHub Desktop.
Iterate over complex structures
const master = [
100,
[
200,
210,
220,
230,
[240, 241, 242, 243, 244, 245, [2450, 2451, 2452, 2454, 2454, 2455]],
250
],
300,
400,
[500, 510, 520, 530, 540],
600,
700,
800,
900
];
function* iterate(arr) {
let search = yield;
let idx;
tree: for (let i = 0; i < arr.length; i++) {
if (search !== undefined && idx === undefined) {
// Once this check is completed once, it will not run again
idx = arr.findIndex(x => x === search);
if (idx >= 0) {
i = idx;
idx = undefined;
}
}
if (Number.isInteger(arr[i])) {
if (search !== undefined && search !== arr[i]) continue;
search = yield arr[i];
if (search !== undefined) idx = undefined; // Reset this so the check in the beggining of the loop can execute again
} else if (Array.isArray(arr[i])) {
const it = iterate(arr[i]);
it.next();
while (true) {
const { value, done } = it.next(search);
if (done) break;
search = yield value;
if (search !== undefined) {
// Check if the inner group contains the searched element before resarting the loop
const found = it.next(search).value;
if (search === found) search = yield found;
else {
// Reset all variables to their initial state and restart the loop to do a full check
idx = undefined;
i = -1;
continue tree;
}
}
}
}
}
}
const it = iterate(master);
it.next(); // Magic! Do not touch!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment