user4261401
user4261401

Reputation:

Loop in js for specific value without if

I use the following code which is working great but I wonder if in JS there is a way to avoid the if and to do it inside the loop, I want to use also lodash if it helps

for (provider in config.providers[0]) {
    if (provider === "save") {
        ....

Upvotes: 2

Views: 124

Answers (6)

It is not clearly stated by the original poster whether the desired output should be a single save - or an array containing all occurrences of save.

This answer shows a solution to the latter case.

const providers = ['save', 'hello', 'world', 'save'];
const saves = [];
_.forEach(_.filter(providers, elem => { return elem==='save' }),
  provider => { saves.push(provider); });
console.log(saves);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.19/lodash.js"></script>

Upvotes: 0

moribvndvs
moribvndvs

Reputation: 42497

You can chain calls together using _.chain, filter by a value, and then use each to call a function for each filtered result. However, you have to add a final .value() call at the end for it to evaluate the expression you just built.

I'd argue that for short, simple conditional blocks, an if statement is easier and more readable. I'd use lodash- and more specifically chaining- if you are combining multiple operations or performing sophisticated filtering, sorting, etc. over an object or collection.

var providers = ['hello', 'world', 'save'];

_.chain(providers)
  .filter(function(provider) {
    return provider === 'save';
  }).each(function(p) {
    document.write(p); // your code here
  }).value();
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.8.0/lodash.js"></script>

Edit: My mistake; filter does not have an overload where you can just supply a literal value. If you want to do literal value checking you have to supply a function as in my amended answer above.

Upvotes: 1

Krzysztof Safjanowski
Krzysztof Safjanowski

Reputation: 7438

Strategy, you are looking for some kind of strategy pattern as,

Currenlty the save is hardcoded but what will you do if its coming from other varible – Al Bundy

var actions = {
  save: function() {
    alert('saved with args: ' + JSON.stringify(arguments))
  },
  delete: function() {
    alert('deleted')
  },
  default: function() {
    alert('action not supported')
  }
}

var config = {
  providers: [{
    'save': function() {
      return {
        action: 'save',
        args: 'some arguments' 
      }
    },
    notSupported: function() {}
  }]
}

for (provider in config.providers[0]) {
  (actions[provider] || actions['default'])(config.providers[0][provider]())
}

Push „Run code snippet” button will shows two pop-ups - be carefull

Upvotes: 0

robertklep
robertklep

Reputation: 203359

Basically, you are testing to see if config.providers[0], which is an object, contains a property called save (or some other dynamic value, I'm using a variable called provider to store that value in my example code below).

You can use this instead of using a for .. in .. loop:

var provider = 'save';
if (config.providers[0][provider] !== undefined) {
  ...
}

Or using @initialxy's (better!) suggestion:

if (provider in config.providers[0]) {
  ...
}

Upvotes: 1

initialxy
initialxy

Reputation: 1183

I'd argue that what you have there is pretty good, clean and readable, but since you mentioned lodash, I will give it a try.

_.each(_.filter(config.providers[0], p => p === 'save'), p => {
    // Do something with p
    ...
});

Note that the arrow function/lambda of ECMAScript 6 doesn't come to Chrome until version 45.

Upvotes: 1

Nitesh Patel
Nitesh Patel

Reputation: 631

How about:

for (provider in config.providers[0].filter(function(a) {return a === "save"}) {
    ...
}

Upvotes: 0

Related Questions