Расширенный выбор jquery... сначала по значению атрибута

Хорошо, я не уверен, как описать то, что я хочу сделать кратко. Итак, возьмите следующий псевдо-HTML:

<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 />

То, что я хочу сделать, это установить все флажки, где они являются первым появлением их соответствующего значения для "myatr". Итак, я хочу взять что-то вроде:

$('input [type=checkbox]') 

и расширить его каким-либо образом, чтобы получить только элементы с идентификаторами chk1, chk3 и chk6, так как они являются первыми экземплярами своих значений myatr (1, 2 и 3 соответственно).

Что-то вроде:

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

Это возможно как-то?

3 ответа

Решение

Решение Зеда, использующее объекты (ведущие себя как хэш-карты), дающее O(1) поисков, а не O(n) поисков Array.

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;
      }
  )

Префикс используется для избежания коллизий со встроенными свойствами объекта.

Я не думаю, что вы можете получить это, просто вызывая встроенные селекторы jQuery. Однако вы можете легко получить это в несколько строк кода.

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;
});

Не проверено, но должно работать.

Примечание. В IE не реализован метод Array.indexOf, но это легко исправить с помощью следующего кода:

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

Не элегантное решение, но вы можете сделать что-то вроде этого:

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 и array_insert должны быть реализованы:)

Другие вопросы по тегам