Andrey Kryukov
Andrey Kryukov

Reputation: 795

how to check if all object keys has false values

JS Object:

var saver = {
        title: false,
        preview: false,
        body: false,
        bottom: false,
        locale: false
};

The question is how to check if all values is false?

I can use $.each() jQuery function and some flag variable, but there may be a better solution?

Upvotes: 40

Views: 89629

Answers (12)

MattCochrane
MattCochrane

Reputation: 3090

Updated version. Thanks @BOB for pointing out that you can use values directly:

Object.values(obj).every((v) => v === false)

Also, the question asked for comparison to false and most answers below return true if the object values are falsy (eg. 0, undefined, null, false), not only if they are strictly false.


This is a very simple solution that requires JavaScript 1.8.5.

Object.keys(obj).every((k) => !obj[k])

Examples:

obj = {'a': true, 'b': true}
Object.keys(obj).every((k) => !obj[k]) // returns false

obj = {'a': false, 'b': true}
Object.keys(obj).every((k) => !obj[k]) // returns false

obj = {'a': false, 'b': false}
Object.keys(obj).every((k) => !obj[k]) // returns true

Alternatively you could write

Object.keys(obj).every((k) => obj[k] == false)
Object.keys(obj).every((k) => obj[k] === false)  // or this
Object.keys(obj).every((k) => obj[k])  // or this to return true if all values are true

See the Mozilla Developer Network Object.keys()'s reference for further information.

Upvotes: 59

Felipe Chernicharo
Felipe Chernicharo

Reputation: 4517

โœ๏ธ This one-liner checks if there's a falsy value inside any object of an array of objects:

const hasFalsyValue = (list) =>
 !list.every(obj => Object.values(obj).every(prop => prop))

I find this one useful to prevent null / falsy values from being passed further on:

const listA = [ { a:'๐ŸŽ', b:100 }, { a:'๐ŸŒ', b:200 } ]

const listB = [ { a:null, b:100 }, { a:'๐ŸŒ', b:200 } ]

// hasFalsyValue(listA) === false
// hasFalsyValue(listB) === true

There's just one detail we should be aware of:

โš ๏ธ In Javascript 0 and '' are Falsy values! โš ๏ธ

So if hasFalsyValue() finds any zero value or any empty string value inside an object in the array, it will consider it a falsy value and thus return true!

...While this might be what you want, sometimes you might want to allow any particular Falsy value to be considered as Truthy.

โœ๐Ÿฝ Say you want to allow zero values in your objects, you can do the following:

const hasFalsyValue_ZeroAllowed =
 (list) => !list.every(obj => Object.values(obj).every(prop =>  prop || prop === 0))

Now zero values won't be considered falsy anymore:


const listC = [ { a:0, b:100 }, { a:'๐ŸŒ', b:200 } ]
const listD = [ { a: null, b:100 }, { a:'๐ŸŒ', b:200 } ]

hasFalsyValue_ZeroAllowed(listC) // false
hasFalsyValue_ZeroAllowed(listD) // true

And you can keep on adding further conditions to the function for a tailored validation:

โœ๐Ÿฝ To allow null values:

const hasFalsyValue_NullAllowed =
 (list) => !list.every(obj => Object.values(obj).every(prop =>  prop || prop === null))

const listE = [ { a: null, b:100 }, { a:'๐ŸŒ', b:200 } ]

hasFalsyValue_NullAllowed(listE) // false

โœ๐Ÿฝ To allow empty string values:

const hasFalsyValue_EmptyStringAllowed =
 (list) => !list.every(obj => Object.values(obj).every(prop =>  prop || prop === ''))

const listF = [ { a: '', b:100 }, { a:'๐ŸŒ', b:200 } ]

hasFalsyValue_EmptyStringAllowed(listF)  // false

Upvotes: 1

Job Gathu
Job Gathu

Reputation: 51

This should work on all major browsers:

Object.keys(saver).every(key => saver[key] === false); // return true

Upvotes: 2

Omer
Omer

Reputation: 3466

Use array.some()

It's more clean and understandable! And it can save us running time, because once the function condition exist once, it goes out of the loop and returns true.

Object.values(obj).some(val => val)

if you actually need strict equality to false write this:

Object.values(obj).some(val => val !== false)

Object.values(obj) make an array with the values of each key.

Upvotes: 15

xlm
xlm

Reputation: 7594

Lodash (3.10.1+) makes this even cleaner to express explicitly:

_.every({a: false, b: false, c: false}, _.negate(Boolean)); // True

But using _.some per ngstschr's answer is more succinct.

Upvotes: 1

ngstschr
ngstschr

Reputation: 2319

With lodash you could also do const allFalse = !_.some(saver);

Upvotes: 1

syntax-punk
syntax-punk

Reputation: 4570

Short and handy one-liner, fully supported by browsers:

Object.keys(saver).every(k => saver[k] === false);

or

Object.values(saver).every(v => v === false);

(careful tho, Object.values() is not supported by IE yet.)

Upvotes: 4

Reinstate Monica Cellio
Reinstate Monica Cellio

Reputation: 26143

This will do the trick...

var result = true;

for (var i in saver) {
    if (saver[i] === true) {
        result = false;
        break;
    }
}

You can iterate objects using a loop, either by index or key (as above).

If you're after tidy code, and not repeating that then simply put it in a function...

Object.prototype.allFalse = function() { 
    for (var i in this) {
        if (this[i] === true) return false;
    }
    return true;
}

Then you can call it whenever you need, like this...

alert(saver.allFalse());

Here's a working sample...

Object.prototype.allFalse = function() { 
    for (var i in this) {
        if (this[i] === true) return false;
    }
    return true;
}

var saver = {
        title: false,
        preview: false,
        body: false,
        bottom: false,
        locale: false
};

console.log("all are false - should alert 'true'");
console.log(saver.allFalse());

saver.body = true;

console.log("one is now true - should alert 'false'");
console.log(saver.allFalse());

Upvotes: 24

deadcoder0904
deadcoder0904

Reputation: 8683

As of Lodash 4.0, overEvery can be used

overEvery(saver, false) loops through every element & checks if its false

It returns true if every element is false otherwise returns false

Upvotes: 0

andersh
andersh

Reputation: 8383

In a comment you ask if you can avoid iteration. You can if you use a javascript library supporting a functional approach, like Underscore, Lodash or Sugar.

With Underscore and Lodash you can write something like this:

var result = _.every(_.values(saver), function(v) {return !v;});

With Sugar you can simply write:

var result = Object.all(saver,false);

Upvotes: 16

iCollect.it Ltd
iCollect.it Ltd

Reputation: 93551

If you want to do it without external iteration (i.e. in your code), try mapping the properties to an array with $.map then using $.inArray to see if any true values exist:

var allFalse = $.inArray(true, $.map(saver, function(obj){return obj})) < 0;

JSFiddle: http://jsfiddle.net/TrueBlueAussie/FLhZL/1/

Upvotes: 1

Balachandran
Balachandran

Reputation: 9637

Do like this,

 for (var i in saver) {
  if (saver[i]) {
    return false; // here if any value is true it wll return as false /
  }
 }
 return true; //here if all value is false it wll return as true

Upvotes: 1

Related Questions