1

I am trying the bind a dropdown list in knockout js, but in my data there are some duplicates is it possible remove these duplicates while binding to the dropdown list?

Here is how i bind the data

<select data-bind="options: availableCountries,
               optionsText: function(item) {
                   return item.countryName + ' (pop: ' + item.countryPopulation + ')'
               },
               value: selectedCountry,
               optionsCaption: 'Choose...'"></select>

var Country = function(name, population) {
    this.countryName = name;
    this.countryPopulation = population;
};

and my viewmodel is as below

var AppViewModel = function() {
this.availableCountries = ko.observableArray([
        new Country("UK", 65000000),
        new Country("USA", 320000000),
        new Country("Sweden", 29000000),
     new Country("Sweden", 29000000)
    ]);
    this.selectedCountry = ko.observable();
};
ko.applyBindings(new AppViewModel());

Here is the js fiddle http://jsfiddle.net/PV7yD/

Thanks,

Praveen.

praveen
  • 351
  • 3
  • 17
  • If it's not important to do this *while* binding I'd suggest making a second computed observable that only has the distinct available countries. In that case your question would become a duplicate of [this one on removing dupes from an array](http://stackoverflow.com/q/2218999/419956). – Jeroen Apr 09 '14 at 13:55

2 Answers2

3

You could use Underscore's _.uniq function in a computed observable, with an iterator that serializes each item to JSON for full comparison. Like this:

this.displayedCountries = ko.computed( function () {
    return _.uniq( this.availableCountries(), false, ko.toJSON );
}, this );

And you could replace ko.toJSON with a function that only returns the countryName property of a country if that's enough to determine uniqueness (which it probably is in this case).

Updated fiddle: http://jsfiddle.net/PV7yD/2/

Martin Wedvich
  • 2,158
  • 2
  • 21
  • 37
0

you can use ko.utils.arrayGetDistinctValues function to get distinct values or you can use filter.

 self.uniqueCountries = ko.dependentObservable(function () {
    var seen = [];
    return self.availableCountries().filter(function (n) {
        return seen.indexOf(n.countryName+'-'+n.countryPopulation) == -1 && seen.push(n.countryName+'-'+n.countryPopulation);
    });
}, self);

view:-

 <select data-bind="options: uniqueCountries,
               optionsText: function(item) {
                   return item.countryName + ' (pop: ' + item.countryPopulation + ')'
               },
               value: selectedCountry,
               optionsCaption: 'Choose...'"></select>

For more info:-

  1. see this

  2. Another Link

FIDDLE DEMO

Community
  • 1
  • 1
Akhlesh
  • 2,389
  • 1
  • 16
  • 23
  • Thanks for the links akhlesh. Is it possible filter based on countryName + Population as unique key instead of just country? – praveen Apr 09 '14 at 14:11
  • Do you mean to say that countryName+Population has uniqueness? If so, then the uniqueness of countryName alone is sufficient. Or did you mean can you _sort_ by Population once you've narrowed the country list to unique values? –  Apr 09 '14 at 14:31