计算出现次数和递增值

时间:2014-05-22 11:23:06

标签: javascript jquery angularjs angularjs-directive angularjs-scope

我有一个带有一些数据的JSON文件,例如:

  $scope.expenses = [
    {
      "amount": "100",
      "SpentOn": "19/04/2014",
      "IsExpensable": true,
    },
    {
      "amount": "200",
      "SpentOn": "20/04/2014",
      "IsExpensable": true,
    },
    {
      "amount": "50",
      "SpentOn": "01/01/2014",
      "IsExpensable": true,
    },
    {
      "amount": "350",
      "SpentOn": "01/09/2013",
      "IsExpensable": false,
    }
  ];

我正在尝试编写一个循环上面的角度函数,当IsExpensable = true时,然后对mm和yyyy执行计数以确定当月有多少费用。因此,在上面的示例中,2014年4月,有2个。在2010年1月,有1个。

继承我的JS:

$scope.MyDateFilterFunction = function () {

      var data = [];
      var dataMonth = [];
      var dataYear = [];
      var Jan = 0;
      var Feb = 0;
      var Mar = 0;
      var Apr = 0;
      var May = 0;
      var May = 0;
      var Jun = 0;
      var Jul = 0;
      var Aug = 0;
      var Sep = 0;
      var Oct = 0;
      var Nov = 0;
      var Dec = 0;

      angular.forEach($scope.expenses, function (value, key) {             

          if (value.IsExpensable) {

              angular.forEach($scope.expenses, function (value, key) {

                data = value.SpentOn.split('/');

                dataMonth = data[1];
                dataYear = data[2];

                var count = (dataMonth.split("04").length - 1)

                console.log("April occurances" + count.length);

                // Add count to var Apr

              });
          }              

      });

      return data;         

  };

我的HTML:

<td ng-repeat="exp in MyDateFilterFunction ()">
    {[{exp}]}
</td>

更新

已添加:

if (dataMonth == "04") {

       Apr = Apr + 1;
       console.log(Apr);
}

然而,控制台输出是: 1 2 3 4 1 2 3 4 1 2 3 4


通过删除第二个angular.forEach语句

解决

2 个答案:

答案 0 :(得分:3)

来自Mike的(以下划线为基础的)答案:
“想象一下,在您自己的代码中为此编写解决方案” - 接受挑战!

var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

$scope.groupped = $scope.expenses
    /* Only give me expensable items */
    .filter(function (exp) {
        return exp.IsExpensable;
    })
    /* Determine each item's group (with friendly display name) */
    .map(function (exp) {
        var dateArr = exp.SpentOn.split('/');
        var groupValue = '' + months[parseInt(dateArr[1]) - 1] + 
                         ' ' + dateArr[2];
        return groupValue;
    })
    /* Map group-names to items-count */
    .reduce(function (groupped, groupValue) {
        groupped[groupValue] = (groupped[groupValue] || 0) + 1;
        return groupped;
    }, {});

<div ng-repeat="(time, count) in groupped">
    {{time}}: {{count}}
</div>

如果(无论出于何种原因)您更喜欢使用数组而不是对象:

$scope.groupped = ...;
$scope.grouppedArr = Object.keys($scope.groupped).map(function (key) {
    return {name: key, count: $scope.groupped[key]};
});

<div ng-repeat="group in grouppedArr">
    {{group.name}}: {{group.count}}
</div>

另请参阅此 short demo


<子> 注1:
在这两种情况下(vanilla JS,下划线),需要额外的逻辑来按月索引对结果进行排序。

<子> 注2:
如果您计划支持旧版本的浏览器(是的,我的意思是IE&lt; 9),您可能希望使用像下划线或lodash这样的库来实现其后备。

答案 1 :(得分:2)

我知道您对使用Underscore持怀疑态度,但我认为这对任何应用程序来说几乎都是必不可少的。在使用库时,请考虑以下问题的答案:

var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']

$scope.data = _.chain($scope.expenses)
  // Only give me expensable items
  .filter(function(exp) {
    return exp.IsExpensable;
  })
  // group them by the month and year (with friendly display string)
  .groupBy(function(exp) {
    var dateAr = exp.SpentOn.split('/');
    var groupValue = '' + months[parseInt(dateAr[1])] + ' ' + dateAr[2];
    return groupValue;
  })
  // Map to a list of objects with time (friendly display string) and number of transactions
  .map(function(group, key) {
    return {
      time: key,
      transactions: group.length
    };
  })
  // End the chain
  .value();

然后在你的html:

<div ng-repeat="item in data">
  {{item.time}}: {{item.transactions}}
</div>

令人难以置信的是,多少下划线可以帮助您的生活更轻松。我保证您在应用程序的多个位置使用它。它也非常轻巧(5kB缩小和gzip)。试想一下,在自己的代码中编写解决方案,同时使其可以移植到应用程序的其他部分。