0

If we have:

var obj = {
  key: [1000, 10, 50, 10]
};

-If the array at the given key is empty, it should return 0.

-If the property at the given key is not an array, it should return 0.

-If there is no property at the given key, it should return 0.

I'm trying to get the average of the elements at the property (key) with a function, getAverageOfElementsAtProperty(obj, 'key').. I managed that part with exception of the 3 points above.

I tried this:

if (obj[key].constructor != Array || !obj.hasOwnProperty(key) || 
    obj[key] == []) {
    return 0;
}

But I'm unsure if using three or operational is the correct move...

4
  • Why you have to do three checks? Just checking if the key existed and the key is not an array is enough. Plus if the key is not defined this will throw an error because you're accessing the constructor property of a potentially not existing property. Commented Feb 1, 2017 at 1:21
  • Why not just use Array.isArray(obj.key) ? Commented Feb 1, 2017 at 1:24
  • @NewToJS the OP wants to check if the Array is not empty too (Array.isArray([]) === true). Commented Feb 1, 2017 at 1:41
  • if (!obj[key] || !Array.isArray(obj.key)) { return 0; } That cleared things out guys, thanks. Just making sure i'm checking two conditions there, if the property exists and if it's an array. Correct? Commented Feb 1, 2017 at 1:59

5 Answers 5

2

You can check multiple conditions like this

if ( 
    typeof obj === 'object' &&      // you have an object
    'key' in object &&              // it contains a "key"
    Array.isArray( obj['key'] )     // it is an array
)
Sign up to request clarification or add additional context in comments.

Comments

1

So for each condition you mentioned it can be done as follows

If the array at the given key is empty, it should return 0.
obj.key.length === 0

If the property at the given key is not an array, it should return 0.
!Array.isArray(obj[key])

If there is no property at the given key, it should return 0.
!obj.hasOwnProperty("key").

You can directly check for a falsy value to check the existence. Also, check if the the value is an array by using the Array.isArray function and then for checking the length of array, use the length property.

if(!obj.hasOwnProperty("key") || !Array.isArray(obj[key]) || obj.key.length === 0)){
return 0;
}

5 Comments

!obj[key] will fail if obj[key] == false. So it's not good practice to see if a property exist or not using that.
@Agalo what if someone uses an object to contain false or null as values then the user wants to check if some property exist or not. Then !obj[key] will exclude the properties that has the values false or null.
For the record, !obj[key] is not the best way to check if a property exists, indeed, as pointed by @ibrahimmahrir. Also, this check is irrelevant, because Array.isArray() can receive undefined and will return false.
@Agalo obj.key is the same as obj["key"]. It checks wether the key "key" exist or not. You should check if a key exist like this obj[key] !== undefined.
hasOwnProperty() and the in operator. would be better to check for existence of property.
0

I like to break up my if into the business logic that it needs to fulfill. I find it easier to understand when I get back to it later on. So I would do it this way

if (!obj.hasOwnProperty(key)) return 0; // If there is no property at the given key
if (!Array.isArray(obj[key])) return 0; // If the property at the given key is not an array
if (obj[key].length === 0) return 0; // If the array at the given key is empty
// add this point we know there is a valid array

Comments

0

You can check, first, [1] if the key exists, then [2] if it's array, and, then, [3] if it's not empty.

Order matters: due to Short-circuit evaluation, if it evaluates true in the first condition, it skips nexts checks (then, you can safely assume that the key exists, that it's an array and so on...)

var obj = {
  key: [1000, 10, 50, 10],
  key2: [],
  key3: "abc"
};


function isValid(obj, key) {
    if (
        (typeof obj[key] === 'undefined') || //If there is no property at the given key (first)
        (!Array.isArray(obj[key])) ||  //If the property at the given key is not an array (IE9>=)
        (obj[key].length == 0) //If the array at the given key is empty,
    ) {
        return 0;
    } else {
        return 1; /* or whathever you want */
    }
}


console.log(isValid(obj, "key")); //1
console.log(isValid(obj, "key2")); //0
console.log(isValid(obj, "key3")); //0
console.log(isValid(obj, "key4")); //0


Note that (typeof obj[key] === 'undefined') is not necessary here, because Array.isArray(undefined) === false (check docs), so, you can skip this check.

1 Comment

Thanks for explaining mrlew
0

if (obj[key].constructor != Array || ... will throw an error if obj[key] is undefined because, then, you'll be accessing constructor of undefined which will throw an error. What you need to do is check if a the value obj[key] exist then if it is an array like this:

if(obj[key] !== undefined || obj[key].constructor != Array)
    return 0;

In general: The or (||) operator will stop checking (evaluating) after the first valid check. Consider check0 || check1 || ... || checkN, if checki is true then checki+1 ... checkN won't be evaluated at all. Because only one valid check is sufficient. Here is an example:

var n = 5;
if(n == 5 || console.log("Here 1"))
  ;

n = 4;
if(n == 5 || console.log("Here 2"))
  ;

As you can see, Here 1 is never loged because the code console.log("Here 1") is never reached.

1 Comment

Good catch, that totally slipped through me. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.