131 votes

Comment faire en sorte que ng-repeat filtre les résultats en doublon

Je fais tourner un simple ng-repeat sur un fichier JSON et je veux obtenir les noms des catégories. Il y a environ 100 objets, chacun appartenant à une catégorie - mais il n'y a qu'environ 6 catégories.

Mon code actuel est le suivant :

  {{place.category}}

La sortie est de 100 options différentes, principalement des doublons. Comment puis-je utiliser Angular pour vérifier si {{place.category}} existe déjà et ne pas créer une option s'il est déjà là ?

edit: Dans mon JavaScript, $scope.places = données JSON, juste pour clarifier

4voto

Erik Trautman Points 497

Voici un exemple simple et générique.

Le filtre :

sampleApp.filter('unique', function() {

  // Prenez la collection et quel champ
  //   devrait être unique
  // Nous supposons ici un tableau d'objets
  // REMARQUE : Nous sautons tout objet qui
  //   contient une valeur dupliquée pour ce
  //   clé particulière. Assurez-vous que c'est ce
  //   que vous voulez !
  return function (arr, targetField) {

    var values = [],
        i, 
        unique,
        l = arr.length, 
        results = [],
        obj;

    // Parcourez tous les objets du tableau
    // et collectez toutes les valeurs uniques
    for( i = 0; i < arr.length; i++ ) {

      obj = arr[i];

      // vérifiez l'unicité
      unique = true;
      for( v = 0; v < values.length; v++ ){
        if( obj[targetField] == values[v] ){
          unique = false;
        }
      }

      // Si c'est vraiment unique, ajoutez sa
      //   valeur à nos valeurs et poussez
      //   sur le tableau retourné
      if( unique ){
        values.push( obj[targetField] );
        results.push( obj );
      }

    }
    return results;
  };
})

La balise :

  {{ item.name }}

4voto

kennasoft Points 1399

J'ai décidé d'étendre la réponse de @thethakuri pour permettre n'importe quelle profondeur pour le membre unique. Voici le code. C'est pour ceux qui ne veulent pas inclure le module AngularUI complet juste pour cette fonctionnalité. Si vous utilisez déjà AngularUI, ignorez cette réponse :

app.filter('unique', function() {
    return function(collection, primaryKey) { //pas besoin de clé secondaire
      var output = [], 
          keys = [];
          var splitKeys = primaryKey.split('.'); //split par période

      angular.forEach(collection, function(item) {
            var key = {};
            angular.copy(item, key);
            for(var i=0; i

Exemple

2voto

commonSenseCode Points 9296

METTRE À JOUR

Je recommandais l'utilisation de Set mais désolé cela ne fonctionne pas pour ng-repeat, ni Map car ng-repeat fonctionne uniquement avec des tableaux. Donc ignorez cette réponse. Quoi qu'il en soit, si vous avez besoin de filtrer les doublons, une façon est comme l'ont dit les autres en utilisant angular filters, voici le lien vers la section de démarrage.


Ancienne réponse

Vous pouvez utiliser la structure de données Set standard de l'ECMAScript 2015 (ES6), au lieu d'une structure de données Array de cette manière vous filtrez les valeurs répétées lors de l'ajout dans le Set. (Rappelez-vous que les ensembles n'autorisent pas les valeurs répétées). Vraiment facile à utiliser :

var mySet = new Set();

mySet.add(1);
mySet.add(5);
mySet.add("some text");
var o = {a: 1, b: 2};
mySet.add(o);

mySet.has(1); // true
mySet.has(3); // false, 3 n'a pas été ajouté à l'ensemble
mySet.has(5); // true
mySet.has(Math.sqrt(25)); // true
mySet.has("Some Text".toLowerCase()); // true
mySet.has(o); // true

mySet.size; // 4

mySet.delete(5); // supprime 5 de l'ensemble
mySet.has(5); // false, 5 a été supprimé

mySet.size; // 3, nous venons de supprimer une valeur

2voto

Helzgate Points 11

J'avais un tableau de chaînes de caractères, pas d'objets et j'ai utilisé cette approche :

ng-repeat="name in names | unique"

avec ce filtre :

angular.module('app').filter('unique', unique);
function unique(){
return function(arry){
        Array.prototype.getUnique = function(){
        var u = {}, a = [];
        for(var i = 0, l = this.length; i < l; ++i){
           if(u.hasOwnProperty(this[i])) {
              continue;
           }
           a.push(this[i]);
           u[this[i]] = 1;
        }
        return a;
    };
    if(arry === undefined || arry.length === 0){
          return '';
    }
    else {
         return arry.getUnique(); 
    }

  };
}

2voto

L S Points 614

Il semble que tout le monde lance sa propre version du filtre unique, donc je vais faire de même. Les critiques sont les bienvenues.

angular.module('myFilters', [])
  .filter('unique', function () {
    return function (items, attr) {
      var seen = {};
      return items.filter(function (item) {
        return (angular.isUndefined(attr) || !item.hasOwnProperty(attr))
          ? true
          : seen[item[attr]] = !seen[item[attr]];
      });
    };
  });

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X