Skip to content

Instantly share code, notes, and snippets.

@mariusGundersen
Created August 21, 2017 14:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mariusGundersen/985189540541189ca80f60b59fa343ac to your computer and use it in GitHub Desktop.
Save mariusGundersen/985189540541189ca80f60b59fa343ac to your computer and use it in GitHub Desktop.
for-of-with proposal
// Given the following generator that will walk a tree structure depth-first
// for each subtree it will go deeper unless the consumer returns `false`
function* depthFirst(tree, prefix=''){
for(const [key, value] of Object.entries(tree)){
const path = `${prefix}/${key}`;
if(typeof value === 'string'){
yield {path, value}
}else{
if(false !== (yield {path})){
yield* depthFirst(value, path);
}
}
}
}
// Run the depth-first walker on this tree
const tree = {
'a': 'A',
'b': {
'c': 'C',
'd': {
'e': 'E'
}
},
'f': 'F'
}
// notice the for-of-with statement below.
// The expression after `with` is evaluated each round, and the
// resulting value is passed to the generator in the `next()` call
let deeper = true;
for(const {path, value} of depthFirst(tree) with deeper){
console.log(path)
deeper = path !== '/b/d'
}
// Run the depth-first walker on this tree
const tree = {
'a': 'A',
'b': {
'c': 'C',
'd': {
'e': 'E'
}
},
'f': 'F'
}
// Wrap the generator in a call to `withFeedback()`, where the second parameter is a
// function that returns the vaule to pass to the generator in the `next()` call
let deeper = true;
for(const {path, value} of withFeedback(depthFirst(tree), () => deeper)){
console.log(path)
deeper = path !== '/b/d'
}
function *withFeedback(iterator, feedback){
try{
while(true){
const next = iterator.next(feedback());
if(next.done){
if(typeof iterator.return === 'Function') iterator.return();
return;
}
yield next.value;
}
}finally{
if(typeof iterator.return === 'Function') iterator.return();
}
}
/a
/b
/b/c
/b/d
/f
// notice that it skips `/b/d/e`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment