(Angular.js) Как посчитать, сколько элементов в массиве по фильтру?

0

В угловом JS у меня есть переменная, которая отслеживает людей и их возраст

$scope.people = [
    {
        name: "Lucy",
        age: "18"
    }, {
        name: "Michael",
        age: "24"
    }, {
        name: "Lisa",
        age: "46"
    }
];

Пользователь может добавить больше людей через простую форму:

<input ng-model="newPerson.name">
<input ng-model="newPerson.age">
<button ng-click="addNewPerson()">Add</button>

В нижней части страницы я хочу простой график пирога, показывающий население по возрастным группам, например (> 18, 18-25, 26-35, 36-45, 45 <). Для этого мне нужно иметь возможность фильтровать $scope.people по возрасту, получить число каждой группы.

Я знаю, что я мог бы использовать обычный javascript для прокрутки всего массива, получения подсчета каждой возрастной группы. И всякий раз, когда добавляется новый человек, просто увеличивайте счет в этой конкретной группе, но мне было интересно, есть ли более эффективный и угловатый способ сделать это?

Теги:

2 ответа

1
Лучший ответ

Здесь один из способов реализовать это с помощью Array.Prototype.filter и Array.Prototype.reduce. Обратите внимание, что фильтр применяется в $scope.ageBrackets который содержит предварительно обработанные данные, подготовленные циклом forEach. Это эффективно для небольших значений диапазона, таких как возраст человека. Это одна из альтернатив, если вы не используете ng-repeat и вы не хотите фильтровать данные несколько раз.

angular.module('ageBracketApp', ['ageBracketApp.controllers']);
angular.module('ageBracketApp.controllers', []).controller('ageBracketController', ['$scope',
  function($scope) {

    $scope.ageBrackets = [];

    $scope.people = [{
      name: "Lucy",
      age: "18"
    }, {
      name: "Michael",
      age: "24"
    }, {
      name: "Lisa",
      age: "46"
    }];

    angular.forEach($scope.people, function(value, key) {
      $scope.ageBrackets[value.age] = $scope.ageBrackets[value.age] + 1 || 1;
    });

    $scope.addPerson = function() {
      var age = Math.floor(Math.random() * (123 - 1 + 1)) + 1; // random between 1 and 123
      $scope.people.push({
        name: 'Person ' + ($scope.people.length + 1),
        age: age
      });
      $scope.ageBrackets[age] = $scope.ageBrackets[age] + 1 || 1;

    };

    $scope.ageBracketCount = function(min, max) {
      max = max || Number.MAX_SAFE_INTEGER;
      return $scope.ageBrackets.filter(function(value, index, array) {
        return index >= min && index <= max;
      }).reduce(function(a, b) {
        return a + b;
      }, 0);
    };
  }
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="ageBracketApp" ng-controller="ageBracketController">
  {{people}}
  <hr />18+: {{ageBracketCount(18)}}
  <br />18-25: {{ageBracketCount(18,25)}}
  <br />26-35: {{ageBracketCount(26,35)}}
  <br />40-: {{ageBracketCount(0,40)}}
  <hr />
  <button ng-click="addPerson()">
    Add person
  </button>
</div>
1

Вы можете использовать такую библиотеку, как lodash: _($scope.people).filter(x => x.age > 18 && x.age <= 25).count()

Кроме того, если вы уже используете отфильтрованный список в ng-repeat, вы можете назначить его как переменную и получить длину, например:

<ul>
    <li ng-repeat="item in people | filter:filterFunction as results"></li>
</ul>
<p>{{results.length}}</p>

function filterFunction(item) {
    return item.age > 18 && item.age <= 25;
}
  • 0
    Обратите внимание, что сглаживание , as доступно в угловых 1.3 и выше.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню