计算observableArray中的重复项并显示它们

时间:2015-04-26 10:14:15

标签: jquery knockout.js

我有一个带有以下数据的可观察数组

["Volkswagen",
 "Toyota",
 "Volkswagen",
 "Toyota",
 "Audi",
 "Volkswagen",
 "Toyota",
 "Audi"]

我想知道如何计算重复值并在我的选择框中显示它们。类似的东西:

Volkswagen (3)
Audi (2)
Toyota (3)

实现这一目标的最佳方法是什么?

3 个答案:

答案 0 :(得分:1)

我可能会使用相当简单的计算机:

viewModel.collapsedMakes = ko.computed({
  pure: true,
  owner: viewModel,
  read: function() {
    var makes = {}, rv;
    // Use an object to count them
    this.makes().forEach(function(make) {
      if (makes[make]) {
        ++makes[make];
      } else {
        makes[make] = 1;
      }
    });

    // Build the array
    rv = Object.keys(makes).sort().map(function(make) {
      return make + " (" + makes[make] + ")";
    });
    return rv;
  }
});

实例:



var viewModel = {
  makes: ko.observableArray([
    "Volkswagen",
    "Toyota",
    "Volkswagen",
    "Toyota",
    "Audi",
    "Volkswagen",
    "Toyota",
    "Audi"
  ])
};

viewModel.collapsedMakes = ko.computed({
  pure: true,
  owner: viewModel,
  read: function() {
    var makes = {}, rv;
    // Use an object to count them
    this.makes().forEach(function(make) {
      if (makes[make]) {
        ++makes[make];
      } else {
        makes[make] = 1;
      }
    });

    // Build the array
    rv = Object.keys(makes).sort().map(function(make) {
      return make + " (" + makes[make] + ")";
    });
    return rv;
  }
});

ko.applyBindings(viewModel, document.body);

<select data-bind="options: collapsedMakes"></select>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

T.J。 Crowder的解决方案很棒,但我想展示他的read函数的简化版本,它利用了Knockout的remove函数:

var arr= ko.observableArray(this.makes().slice()),
        s= [];

arr.sort().forEach(function(val) {
  var len= arr.remove(val).length;
  s.push(val+' ('+len+')');
});

return s;

使用slice克隆原始数组,因此这是非破坏性的。

&#13;
&#13;
var viewModel = {
  makes: ko.observableArray([
    "Volkswagen",
    "Toyota",
    "Volkswagen",
    "Toyota",
    "Audi",
    "Volkswagen",
    "Toyota",
    "Audi"
  ])
};

viewModel.collapsedMakes = ko.computed({
  pure: true,
  owner: viewModel,
  read: function() {
    var arr= ko.observableArray(this.makes().slice()),
        s= [];

    arr.sort().forEach(function(val) {
      var len= arr.remove(val).length;
      s.push(val+' ('+len+')');
    });

    return s;
  }
});

ko.applyBindings(viewModel, document.body);
&#13;
<select data-bind="options: collapsedMakes"></select>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

本着DRY的精神,我建议您查看http://linqjs.codeplex.com/

这将为您提供水疗中的大部分LINQ客户端。求和只是您可以在一行代码中完成的事情之一。