2009-07-28 12 views
0

Bon, je ne suis pas sûr de savoir comment décrire de façon concise ce que je veux faire. Alors, prenez le pseudo-html suivant:sélection jquery avancée ... d'abord par valeur d'attribut

<input type=checkbox id=chk1 myatr=1 /> 
<input type=checkbox id=chk2 myatr=1 /> 
<input type=checkbox id=chk3 myatr=2 /> 
<input type=checkbox id=chk4 myatr=1 /> 
<input type=checkbox id=chk5 myatr=2 /> 
<input type=checkbox id=chk6 myatr=3 /> 

Ce que je veux faire est de sélectionner toutes les cases où ils sont la première occurrence de leur valeur respective pour « myatr ». Donc, je veux prendre quelque chose comme:

$('input [type=checkbox]') 

et l'étendre en quelque sorte à ne recevoir que les articles avec ids chk1, chk3 et chk6, car ils sont les premiers cas de leurs valeurs de myatr (1, 2 et 3 respectivement).

Quelque chose comme:

$('input [type=checkbox]').FirstForEach('myatr') 

Est-ce possible en quelque sorte?

Répondre

1

solution de Zed en utilisant des objets (se comporter comme hashmaps) donnant O (1), par opposition lookups à O (n) recherche de tableau.

var attrs = {}; 
var prefix = "blah$$"; 
$("input [type=checkbox]"). 
    filter(
    function() { 
     attr = this.attr("myatr"); 
     if (attrs[prefix + attr]) { 
     return false; 
     } else { 
     attrs[prefix + attr] = true; 
     return true; 
     } 
) 

Un préfixe est utilisé pour éviter les collisions avec les propriétés intégrées de l'objet.

+0

Il serait intéressant de mesurer combien de temps la liste d'attributs nécessaire pour que o (1) de hachage passe en dessous de l'o (n) d'accès au tableau. – Zed

+0

Performance sage, il doit être un très long tableau (1000+) éléments à prendre en compte. Mais les objets sont justes dans ce but. Regardez aussi le code supplémentaire que vous devez écrire en implémentant array_contains. –

1

Pas une solution élégante, mais vous pouvez faire quelque chose comme ceci:

var attrs = new Array(); 

$("input [type=checkbox]"). 
    filter(
    function() { 
     attr = this.attr("myatr"); 
     if (array_contains(attrs, attr)) { 
     return false; 
     } else { 
     array_insert(attrs, attr); 
     return true; 
     } 
). 
    ... 

array_contains et array_insert devraient être mises en œuvre :)

+0

Vous ne devriez pas utiliser 'new Array()' dans JS, vous devriez juste utiliser '[]' – RaYell

+0

Vous pouvez simplement utiliser attrs.push (attr) au lieu de array_insert (attrs, attr) – montrealist

1

Je ne pense pas que vous pouvez obtenir ce juste d'appeler jQuery Build- dans les sélecteurs. Cependant, vous pouvez facilement obtenir ceci dans quelques lignes de code.

var ids = []; 
$('input[type=checkbox]').filter(function (index) { 
    var attr = $(this).attr('myattr'); 
    if (ids.indexOf(attr) !== -1) { 
     ids[ids.length] = attr; 
     return true; 
    } 
    return false; 
}); 

Non testé, mais devrait fonctionner.

Note: IE n'a pas la méthode mise en œuvre Array.indexOf mais vous pouvez facilement corriger cela avec ce code:

[].indexOf || (Array.prototype.indexOf = function(v){ 
    for (var i = 0; i < this.length; i++) { 
     if (v === this[i]) { 
      return i; 
     } 
    } 
    return -1; 
}); 
+0

Un tableau n'est pas vraiment Champs obligatoires. Vous pouvez simplement utiliser un objet comme hashmap pour des résultats plus rapides. –

Questions connexes