【问题标题】:Counting number of occurances and incrementing value计算出现次数和递增值
【发布时间】:2014-05-22 11:23:05
【问题描述】:

我有一个带有一些数据的 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 语句解决

【问题讨论】:

  • 签出 underscore.js: underscorejs.org
  • @DavinTryon - 谢谢你的建议,我看看。但是我不希望将任何其他库导入我的应用程序
  • @OamPsy:您尝试过以下任何解决方案吗?它对你有用吗?如果是这样,请将其标记为已接受(如果您喜欢,请点赞)。
  • @ExpertSystem - 是的,我暂时同意你的想法,因为它允许我继续我的项目,尽管我可能需要在稍后阶段重新访问。

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


【解决方案1】:

来自 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

【讨论】:

  • 你赢了这一轮,@ExpertSystem!!
  • :) 正如我所说,这是一个偏好和要求的问题(例如 _ 将是支持旧浏览器等的更好选择)。我只是想指出(在这种特殊情况下)易于实现不应该成为使用 _ 的论据。
【解决方案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 压缩)。想象一下,在您自己的代码中编写一个解决方案,同时使其可移植到您应用程序的其他部分。

【讨论】:

  • 我想象出来的,我喜欢我所看到的 :) 库适用于某些任务和某些约束或要求。但它们并不是所有问题的答案。尽管如此,它们确实有一点(除其他外)是无价的:与旧的(或蹩脚的)浏览器的兼容性。
猜你喜欢
  • 2012-10-20
  • 1970-01-01
  • 1970-01-01
  • 2010-11-23
  • 1970-01-01
  • 1970-01-01
  • 2021-10-10
  • 1970-01-01
相关资源
最近更新 更多