9

So I need to pass in a object where each of its properties are arrays. The function will use the information held in each array, but I want to check if the whole object is empty empty (not just having no properties) by checking if each of its arrays are empty/null as well. What I have so far:

function isUnPopulatedObject(obj) { // checks if any of the object's values are falsy
    if (!obj) {
        return true;
    }

    for (var i = 0; i < obj.length; i++) {
        console.log(obj[i]);
        if (obj[i].length != 0) {
            return false;
        }    
    }

    return true;  
}

So for example, this would result in the above being false:

obj {
    0: Array[0]
    1: Array[1]
    2: Array[0]
}

While this is the empty I'm checking for (so is true):

obj {
    0: Array[0]
    1: Array[0]
    2: Array[0]
}

The above code doesn't work. Thanks in advance.

LaLaLottie
  • 393
  • 1
  • 4
  • 17

5 Answers5

12

So if we want to go through the object and find if every key of that object passes a check, we can use Object.keys and the Array#extra every like so:

var allEmpty = Object.keys(obj).every(function(key){
return obj[key].length === 0
})

This will set allEmpty to a boolean value (true/false), depending on if every time we run the given check obj[key].length === 0 returns true or not.

This object sets allEmpty to true:

var obj = {
    0: [],
    1: [],
    2: []
}

while this sets it to false:

var obj = {
    0: [],
    1: [],
    2: [],
    3: [1]
}
Tim Roberts
  • 1,120
  • 2
  • 9
  • 25
2

An object doesn't have a length property. There are several other ways to loop through an object's values, which you should be able to find.

To check if a value is an array, you can use Array.isArray.

For example:

function objectIsEmpty(obj) {
    return Object.keys(obj).every(function(key) {
      var val = obj[key];  
      
      if (Array.isArray(val) && val.length === 0) {
        return true;
      }
      
      // Other rules go here:
      // ...
      
      return false;
    });
};


console.log(objectIsEmpty({ 0: [], 1: [], 2: [] }));
console.log(objectIsEmpty({ 0: [], 1: [1], 2: [] }));
Community
  • 1
  • 1
user3297291
  • 22,592
  • 4
  • 29
  • 45
2

It might be interesting to start using the new kid in town. Object.values()

var o1 = {0: [], 1: [1], 2: []},
    o2 = {0: [], 1: [], 2: []},
chkObj = o => Object.values(o).every(a => a.length === 0);
console.log(chkObj(o1));
console.log(chkObj(o2));

Note: This should work only on the newest versions of Chrome, Opera and FF

Redu
  • 25,060
  • 6
  • 56
  • 76
1

it is not working since your object doesn't have length property.

Try this simple one

function isUnPopulatedObject(obj) { 
    return Object.keys( obj ).filter( function(key){
      return obj[ key ].length > 0;  //if any array has a property then filter will return this key.
    }).length == 0; //used == here since you want to check if all are empty
}

or use every

function isUnPopulatedObject(obj) { 
    return Object.keys( obj ).every( function(key){
      return obj[ key ].length == 0;  
    }); 
}

or use some

function isUnPopulatedObject(obj) { 
    return Object.keys( obj ).some( function(key){
      return obj[ key ].length > 0;  
    }) === false; 
}
gurvinder372
  • 66,980
  • 10
  • 72
  • 94
1

It's mentioned / done in some other answers (though not the currently accepted answer), but not emphasized:

It's not sufficient to loop over every key and verify the length; one needs to verify the type of the key value, as well, e.g. something like:

function isEmptyArray(arg) {
   return Array.isArray(arg) && arg.length === 0
}

function isObjectWhoseValuesAreAllEmptyArrays(o) {
  return Object.values(o).every( (v) => isEmptyArray(v) )        
}

Where you can modify isEmptyArray depending on the desired behaviour (e.g. throw an error if any of the keys aren't arrays vs. just returning false).


E.g. of cases where some of the other proposed solutions may fail:

var allEmpty = Object.keys(obj).every(function(key){
return obj[key].length === 0
})

and

chkObj = o => Object.values(o).every(a => a.length === 0);

will return undefined for:

  • obj = { a: [], b: '' }, or
  • obj = { a: [], b: {} }, or
  • obj = { a: [], b: null },
  • etc

Rax Adaam
  • 790
  • 3
  • 11