2015-05-19 2 views
1

У меня есть несколько объектов внутри массива в Javascript. Объект выглядит следующим образом:Значения свойств объекта Tally Javascript

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

Я хочу, чтобы перебрать этот массив объектов, а также подсчитывать количество checked: true значений имеются. Если все они равны true, я хочу запустить функцию. Как мне узнать, все ли значения checked равны true?

+1

Проверка правильности пути ES6: 'model.every (a => a.checked)'. – Xufox

+1

@Xufox, или 'model.every (function (item) {return item.checked})' для браузеров, не относящихся к ES6. – royhowie

ответ

2

Самый простой способ сделать это было бы использовать 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 
} 

редактировать

Как отметил @Bergi, это быстрее использовать Array.prototype.every решение от the comments above, так как .every заканчивается на в первом случае возвращается обратный вызов false:

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

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

Хотя, если вы после исполнения, это даже быстрее использовать для цикла:

var allChecked = function (arr) { 
    for (var i = arr.length; --i;) 
     if (!arr[i].checked) return false; 
    return true; 
} 
+0

Ouch, no. Не самый легкий из них (и не исполнитель). Почему бы не использовать '.every', как вы уже высказали в комментариях? – Bergi

+0

@Bergi '.reduce' возвращает количество элементов, где' item.checked === true', а не только двоичный true/false, который может быть полезен OP – royhowie

+0

OP не упоминает подсчет ? Да, если ему нужно число, то можно использовать 'сокращение', но для определения« * ли все они равны «true», «каждый» - соответствующий инструмент. – Bergi

1

Как Xufox и royhowie предложил, every() является оптимальным выбором:

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

Если вы хотел играть с прототипами:

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 держаться подальше от прототипов по различным причинам (в частности, не р rototype - базовый класс Object или Array). Вышеприведенный пример ужасный пример и должен никоим образом не используется (слишком много вопросов, чтобы указать вкратце).

Важно отметить, что приведенное выше является лишь быстрым примером, чтобы продемонстрировать, как вы можете сделать что-то еще english (например, arr.countWhenField('checked').isEqualTo(true) == arr.length).

Смежные вопросы