Reputation: 2727
Let's say I have a handful of functions that do things:
function doStuff() { console.log('doing stuff'); }
function doThings() { console.log('doing things'); }
function doIt() { console.log('doing it'); }
function doThis() { console.log('doing this'); }
function doThat() { console.log('doing that'); }
And then just as many that disable their behaviors:
function stopStuff() { console.log('stopping stuff'); }
function stopThings() { console.log('stopping things'); }
function stopIt() { console.log('stopping it'); }
function stopThis() { console.log('stopping this'); }
function stopThat() { console.log('stopping that'); }
Then I put all the 'do' functions in an object so I can dynamically access them by setting what
:
var what = 'things';
var doing = {
stuff: function() { doStuff(); },
things: function() { doThings(); },
it: function() { doIt(); },
this: function() { doThis(); },
that: function() { doThat(); }
};
doing[what](); //console logs 'doing things'
Is there a way to go about enabling one do
function while iterating through all the non-matching stop
functions?
For example, if I do var what = 'this'; doing[what]();
, I want it to not only doThis();
but also stopStuff(); stopThings(); stopIt(); stopThat();
I'm having trouble coming up with an elegant method that doesn't involve lengthy if statements or case/switch.
Upvotes: 0
Views: 62
Reputation: 1
If all your do/stop functions are global - this works
function doStuff() { console.log('doing stuff'); }
function doThings() { console.log('doing things'); }
function doIt() { console.log('doing it'); }
function doThis() { console.log('doing this'); }
function doThat() { console.log('doing that'); }
function stopStuff() { console.log('stopping stuff'); };
function stopThings() { console.log('stopping things'); };
function stopIt() { console.log('stopping it'); };
function stopThis() { console.log('stopping this'); };
function stopThat() { console.log('stopping that'); };
var run = function(root) {
var fnNames = ['stuff', 'things', 'it', 'this', 'that'];
return function(what) {
fnNames.forEach(function (fn) {
var fnName = fn[0].toUpperCase() + fn.slice(1);
root[(what == fn ? 'do' : 'stop') + fnName]();
});
};
}(window);
// usage
console.log('things');
run('things');
console.log('this');
run('this');
However, if they are not global, it's a little messier, but not by much
function doStuff() { console.log('doing stuff'); }
function doThings() { console.log('doing things'); }
function doIt() { console.log('doing it'); }
function doThis() { console.log('doing this'); }
function doThat() { console.log('doing that'); }
function stopStuff() { console.log('stopping stuff'); }
function stopThings() { console.log('stopping things'); }
function stopIt() { console.log('stopping it'); }
function stopThis() { console.log('stopping this'); }
function stopThat() { console.log('stopping that'); }
var run = (() => {
var fns = {
stuff: { run: doStuff, stop: stopStuff },
things: { run: doThings, stop: stopThings },
it: { run: doIt, stop: stopIt },
"this": { run: doThis, stop: stopThis },
that: { run: doThat, stop: stopThat }
};
return what => Object.keys(fns)
// include the sort only if you need to stop all first before start
// change a == what to b == what to start selected and then stop the rest
.sort((a,b) => a == what)
.forEach(key => fns[key][what == key ? 'run' : 'stop']());
})();
console.log('things');
run('things');
console.log('this');
run('this');
Upvotes: 3
Reputation: 1253
Two way you can do it depending on the running a extra function cost.
OR filter the particular stop function.
function doStuff() {
console.log('doing stuff');
}
function doThings() {
console.log('doing things');
}
function doIt() {
console.log('doing it');
}
function doThis() {
console.log('doing this');
}
function doThat() {
console.log('doing that');
}
function stopStuff() {
console.log('stopping stuff');
}
function stopThings() {
console.log('stopping things');
}
function stopIt() {
console.log('stopping it');
}
function stopThis() {
console.log('stopping this');
}
function stopThat() {
console.log('stopping that');
}
var what = 'things';
var doing = {
stuff: function() {
doStuff();
},
things: function() {
doThings();
},
it: function() {
doIt();
},
this: function() {
doThis();
},
that: function() {
doThat();
}
};
var stopping = {
stuff: function() {
stopStuff();
},
things: function() {
stopThings();
},
it: function() {
stopIt();
},
this: function() {
stopThis();
},
that: function() {
stopThat();
}
};
var stopKeys = Object.keys(stopping);
function stopsOthers(doing) {
arr = stopKeys.filter(function(item) {
return item !== doing;
});
arr.forEach(function(key) {
stopping[key]();
});
}
stopsOthers(what);
doing[what]();
Upvotes: 1
Reputation: 3782
function doStuff() { console.log('doing stuff'); }
function doThings() { console.log('doing things'); }
function doIt() { console.log('doing it'); }
function doThis() { console.log('doing this'); }
function doThat() { console.log('doing that'); }
function stopStuff() { console.log('stopping stuff'); }
function stopThings() { console.log('stopping things'); }
function stopIt() { console.log('stopping it'); }
function stopThis() { console.log('stopping this'); }
function stopThat() { console.log('stopping that'); }
var what = 'things';
var doing = {
stuff: doStuff,
things: doThings,
it: doIt,
this: doThis,
that: doThat
};
var stopping = {
stuff: stopStuff,
things: stopThings,
it: stopIt,
this: stopThis,
that: stopThat
};
var a = Object.keys(stopping);
a.splice(a.indexOf(what), 1);
Object.keys(stopping).map(function(key) {
return stopping[key]();
});
doing[what]();
Upvotes: 2
Reputation: 543
Let the functions take a parameter, and iterate through an array of functions that call each of them except the parameter. Example:
var doing = [
stuff: function(func) {
stopping.forEach(element => {
if (element !== func) {
element()
}
}
doStuff()
},
...
];
var stopping = [
stopStuff: function() { stoppingStuff() },
...
];
Upvotes: 1
Reputation: 284
You can use a simple for loop as in the following code
If all your do/stop functions are global - this works
for(var idx in doing) {
if(idx == what) {
doing[idx]();
}
else {
var fn = idx.charAt(0).toUpperCase() + idx.slice(1);
var fname = "stop"+fn;
window[fname]();
}
}
Upvotes: 1