1

I have several objects inside of an array in Javascript. The object looks like this:

        model: [
            {
                category: 'Media',
                value: '',
                checked: false
            },
            {
                category: 'Entertainment',
                value: '',
                checked: false
            },
            {
                category: 'Music',
                value: '',
                checked: false
            },
            {
                category: 'Theater',
                value: '',
                checked: false
            }
        ]

I want to loop through this array of objects, and tally up the number of checked: true values there are. If all of them equal true, I want to run a function. How do I go about seeing if all of the checked values are equal to true?

2
  • 1
    Checking if all of them are true the ES6 way: model.every(a=>a.checked). Commented May 19, 2015 at 1:22
  • 1
    @Xufox, or model.every(function (item) { return item.checked }) for non-ES6 browsers Commented May 19, 2015 at 1:25

2 Answers 2

2

The easiest way to do this would be to use Array.prototype.reduce:

var aggregate = function (arr) {
    return arr.reduce(function (p, c) {
        return c.checked ? p + 1 : p;
    }, 0);
}

if (aggregate(model) === model.length) {
    // call your function
}

edit

As pointed out by @Bergi, it's faster to use the Array.prototype.every solution from the comments above, since .every terminates on the first instance the callback returns false:

var allChecked = function (arr) {
    return arr.every(function (item) {
        return item.checked;
    });
}

if (allChecked(model)) {
    // call your function
}

Although, if you're after performance, it's even faster to use a for-loop:

var allChecked = function (arr) {
    for (var i = arr.length; --i;)
        if (!arr[i].checked) return false;
    return true;
}
Sign up to request clarification or add additional context in comments.

5 Comments

Ouch, no. Not the easiest for sure (and not performant either). Why not use .every as you already suggested in the comments?
@Bergi .reduce has the effect of returning the number of items where item.checked === true, instead of just a binary true/false, which could be of use to the OP
OP did not mention counting? Yes, if he needs the number, then one would use reduce, but to determine "whether all of them equal true", everyis the appropriate tool.
@Bergi also added a for-loop solution, since that yields the best performance
@royhowie for-loop is faster for now. every() is still kind of new and likely to be optimized at some point
1

As Xufox and royhowie suggested, every() is the optimum choice:

obj.model.every(val=>val.checked); // ES6
obj.model.every(function(val){ return val.checked; }); //ES5.1+

If you wanted to play with prototypes:

Array.prototype.countWhenField = function(field){this._field=field; return this};
Array.prototype.isEqualTo = function(val){
    var arr = this,
        fld = this._field;

    // using reduce() here as an example, but can use every()
    return arr.reduce(function (prev, curr) {
        return curr[fld] == val ? prev + 1 : prev;
    },0);
};

var obj = { 
  model : [
            {
                category: 'Media',
                value: '',
                checked: true
            },
            {
                category: 'Entertainment',
                value: '',
                checked: true
            },
            {
                category: 'Music',
                value: '',
                checked: false
            },
            {
                category: 'Theater',
                value: '',
                checked: true
            }
          ]
};

console.log(
  obj.model.countWhenField('checked').isEqualTo(true), // 3
  obj.model.length                                     // 4
);

Advice is to stay away from prototypes for various reasons (especially don't prototype the base Object or Array class). The above is a horrible example and should not by any means be used in production code (too many issues to point out in a short time).

It is important to note that the above is only a quick example to demonstrate how you can make something more english (e.g., arr.countWhenField('checked').isEqualTo(true) == arr.length).

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.