daveycroqet
daveycroqet

Reputation: 2727

Elegantly Toggling Many Functions

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

Answers (5)

Jaromanda X
Jaromanda X

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

gusaindpk
gusaindpk

Reputation: 1253

Two way you can do it depending on the running a extra function cost.

  1. Call all the stop function before starting a new do function.
  2. 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

Vineesh
Vineesh

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

Nic Bonetto
Nic Bonetto

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

huydq5000
huydq5000

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

Related Questions