Quitch
Quitch

Reputation: 89

Push string to array if the array you want to push from is undefined

I am not a coder, I am messing around with some JavaScript as part of modding a game, so bear with me. This game supports es5/everything Chromium 28 supported.

I had code which pushed a string to an array from a variable, and when the variable was undefined a fixed string was pushed instead:

       slotsArray.push({
          landing_policy: ai.landing_policy || 'no_restriction'
        });

The setup changed such that where ai.landing_policy was set it would contain multiple values, so it become an array. When it wasn't set only a single entry was required.

The same code does not appear to work where an array is in place:

        for (var i = 0; i < count; i++) {
          slotsArray.push({
            landing_policy: ai.landing_policy[i] || 'no_restriction'
          });
        }

An error is produced because it's trying to check a value from a variable that hasn't been defined. I expected that to cause it to use the fixed value, but apparently that's not what happens, it just fails.

I've changed my approach to the code seen below in full:

      if (Array.isArray(ai.landing_policy)) {
        for (var i = 0; i < count; i++) {
          slotsArray.push({
            landing_policy: ai.landing_policy[i]
          });
        }
      }
      else {
        slotsArray.push({
          landing_policy: ai.landing_policy || 'no_restriction'
        });
      }

This code works, but what I'm looking to understand is whether this was the best solution? The old method felt elegant, while the new one looks a little clumsy.

Upvotes: 1

Views: 184

Answers (2)

iwaduarte
iwaduarte

Reputation: 1700

Elegant solution not always converse to the most readable/desirable. I would probably do something like:

 const formattedPolicy = ai.landing_policy.map(policy => policy || 'no_restriction');
 slotsArray = [...formattedPolicy ];

Course this has to imply that the ai.landing_policy is always an array. If you need to double check first you could also do:

const formattedPollicy = ai.landing_policy.constructor === Array 
               ? ai.landing_policy.map(policy => policy || 'no_restriction');
               : [ai.landing_policy]

Looks like an elegant or short imho but your code is way more readable.

Upvotes: 1

FZs
FZs

Reputation: 18619

You can use the ternary operator(? :).

It will return the second value if the first is true, and the third otherwise.

I've used array instanceof Array instead of Array.isArray(array) to support ES5.

var isArray = ai.landing_policy instanceof Array
for (var i = 0; i < (isArray ? count : 1); i++) {
    slotsArray.push({
        landing_policy: isArray ? ai.landing_policy[i] : ai.landing_policy || 'no_restriction'
    });
}

Upvotes: 1

Related Questions