2010-07-04 5 views
0

J'ai un tableau d'éléments (terms), qui seront mis en <option> balises dans un <select> Si l'un de ces éléments se trouvent dans un autre tableau (termsAlreadyTaking), ils doivent d'abord enlever Voici comment je l'ai fait:..Une meilleure façon de voir si un tableau contient un objet?

// If the user has a term like "Fall 2010" already selected, we don't need that in the list of terms to add. 
    for (var i = 0; i < terms.length; i++) 
    { 
     for (var iAlreadyTaking = 0; iAlreadyTaking < termsAlreadyTaking.length; iAlreadyTaking++) 
     { 
      if (terms[i]['pk'] == termsAlreadyTaking[iAlreadyTaking]['pk']) 
      { 
       terms.splice(i, 1); // remove terms[i] without leaving a hole in the array 
       continue; 
      } 
     } 
    }  

est-il une meilleure façon de le faire? il se sent un peu maladroit.

J'utilise jQuery, si cela fait une différence.

MISE à JOUR sur la base de la réponse de @Matthew Flaschen :

// If the user has a term like "Fall 2010" already selected, we don't need that in the list of terms to add. 
var options_for_selector = $.grep(all_possible_choices, function(elem) 
          { 
           var already_chosen = false; 
           $.each(response_chosen_items, function(index, chosen_elem) 
           { 
            if (chosen_elem['pk'] == elem['pk']) 
            { 
             already_chosen = true; 
             return; 
            } 
           }); 
           return ! already_chosen; 
          }); 

La raison pour laquelle il obtient au milieu un peu plus bavard est que $.inArray() est soit faux, parce que les doublons que je cherche ne pas strictement égal à un autre dans le sens ==. Cependant, toutes leurs valeurs sont les mêmes. Puis-je le rendre plus concis?

+2

'splice' est pas exactement rapide. Il pourrait être préférable d'ajouter les éléments choisis à un nouveau tableau au lieu de supprimer le reste de l'original. – casablanca

Répondre

3
var terms = $.grep(terms, function(el) 
      { 
       return $.inArray(el, termsAlreadyTaking) == -1; 
      }); 

Cela a encore m * performance n (m et n sont les longueurs des tableaux), mais il ne devrait pas être un gros problème aussi longtemps qu'ils sont relativement faibles. Pour obtenir m + n, vous pouvez utiliser une table de hachage

Notez que ECMAScript fournit le tableau similaire. filter et Array. indexOf. Cependant, ils ne sont pas encore implémentés dans tous les navigateurs, donc vous devrez utiliser les implémentations MDC comme solution de secours. Puisque vous utilisez jQuery, grep et inArray (qui utilise natif indexOf quand il est disponible) sont plus faciles.

EDIT:

Vous pouvez faire:

var response_chosen_pk = $.map(response_chosen_items, function(elem) 
{ 
    return elem.pk; 
}); 
var options_for_selector = $.grep(all_possible_choices, function(elem) 
{ 
    return $.inArray(elem.pk, response_chosen_pk) == -1; 
}); 
+1

Est-ce que IE supporte 'indexOf' sur les tableaux? – Matchu

+0

Trouvé - [fonctionne dans tous sauf IE6] (http://stackoverflow.com/questions/143847/best-way-to-find-an-item-in-a-javascript-array/143863#143863). Devrait probablement juste utiliser '$ .inArray' pour éviter la question. – Matchu

+0

@Matchu, vous avez raison. J'ai changé pour inArray (bien que vous puissiez utiliser l'implémentation de MDC comme solution de secours). –

0

http://github.com/danstocker/jorder

Créer une table Jörder sur termsAlreadyTaking, et l'indice avec pk.

var table = jOrder(termsAlreadyTaking) 
    .index('pk', ['pk']); 

Ensuite, vous pouvez lancer une recherche beaucoup plus rapide:

... 
if ([] == table.where([{ pk: terms[i].pk }])) 
{ 
    ... 
} 
... 
Questions connexes