2010-07-13 2 views
11

У меня есть массив объектов. Каждый объект имеет, помимо прочего, атрибут идентификатора. Я хочу найти индекс в массиве объекта с определенным идентификатором. Есть ли элегантный и простой способ сделать это в jQuery?jQuery: индекс элемента в массиве, где предикат

+0

Точно, что я также ищу. Слишком плохо нет элегантного решения действительно ... – epeleg

ответ

4

В этом случае вы должны использовать цикл for в javascript вместо использования jQuery. См путь 3 в http://net.tutsplus.com/tutorials/javascript-ajax/10-ways-to-instantly-increase-your-jquery-performance/

ОБНОВЛЕНО: JQuery написано в JavaScript, и он не может быть быстрее, чем другой код, написанный также в JavaScript. jQuery очень хорош, если вы работаете с DOM, но на самом деле не помогаете, если работаете с простыми массивами или объектами javascript.

Код, который вы ищете может быть что-то вроде этого:

for (var i=0, l = ar.length; i<l; i++) { 
    if (ar[i].ID === specificID) { 
     // i is the index. You can use it here directly or make a break 
     // and use i after the loop (variables in javascript declared 
     // in a block can be used anywhere in the same function) 
     break; 
    } 
} 
if (i<l) { 
    // i is the index 
} 

Важно то, что вы должны провести некоторые простые JavaScript правила: Всегда объявлять локальные переменные (не забудьте var перед объявлением переменной) и кэш любые свойства или индексы, которые вы используете более одного раза в локальной переменной (например, ar.length выше). (См, например http://wiki.forum.nokia.com/index.php/JavaScript_Performance_Best_Practices)

3

Не очень элегантный, но милый трюк:

var index = parseInt(
    $.map(array, function(i, o) { return o.id === target ? i : ''; }).join('') 
); 

Jquery не имеет много функциональных конструкций, как это; философия библиотеки действительно сфокусирована на работе DOM-споров. Они даже не добавят функцию .reduce(), потому что никто не может подумать о причине, которая была бы полезной для основных функций.

В библиотеке Underscore.js много таких возможностей, и она «играет хорошо» с jQuery.

+0

приятный, но неэффективный, поскольку он проходит через все элементы массива ... Если вы перейдете через них, вы можете просто создать обратный хеш, чтобы вы могли ответить Q на многие "specificID" s. – epeleg

+0

@epeleg хорошо да, понятно. – Pointy

5
 
See [`Array.filter`][1] to filter an array with a callback function. Each object in the array will be passed to the callback function one by one. The callback function must return `true` if the value is to be included, or false if not. 

    var matchingIDs = objects.filter(function(o) { 
     return o.ID == searchTerm; 
    }); 

All objects having the ID as searchTerm will be returned as an array to matchingIDs. Get the matching element from the first index (assuming ID is unique and there's only gonna be one) 

    matchingIDs[0]; 

    [1]: https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter 

Обновление:

заказ findIndex из ECMAScript 6.

items.findIndex(function(item) { item.property == valueToSearch; }); 

Поскольку findIndex не доступен в большинстве браузеров все же, вы могли бы засыпку с использованием этого implementation:

if (!Array.prototype.findIndex) { 
    Array.prototype.findIndex = function(predicate) { 
    if (this == null) { 
     throw new TypeError('Array.prototype.findIndex called on null or undefined'); 
    } 
    if (typeof predicate !== 'function') { 
     throw new TypeError('predicate must be a function'); 
    } 
    var list = Object(this); 
    var length = list.length >>> 0; 
    var thisArg = arguments[1]; 
    var value; 

    for (var i = 0; i < length; i++) { 
     value = list[i]; 
     if (predicate.call(thisArg, value, i, list)) { 
     return i; 
     } 
    } 
    return -1; 
    }; 
} 
+2

ОП спросил, как получить индекс элемента, а не сам элемент. – epeleg

+0

@epeleg - Я не читал вопрос правильно, кажется. Прохождение через каждый объект и разбивка, когда матч найден, - это путь, который предложил Олег. – Anurag

0

Используйте jOrder. http://github.com/danstocker/jorder

Подайте свой массив в таблицу jOrder и добавьте индекс в поле «ID».

var table = jOrder(data) 
    .index('id', ['ID']); 

Затем получить индекс массива элемента по:

var arrayidx = table.index('id').lookup([{ ID: MyID }]); 

Если вы хотите всю строку, а затем:

var filtered = table.where([{ ID: MyID }]); 

вуаля.

1

Для этого нет встроенных методов; метод [].indexOf() не принимает предикат, так что вам нужно что-то обычай:

function indexOf(array, predicate) 
{ 
    for (var i = 0, n = array.length; i != n; ++i) { 
     if (predicate(array[i])) { 
      return i; 
     } 
    } 
    return -1; 
} 

var index = indexOf(arr, function(item) { 
    return item.ID == 'foo'; 
}); 

Функция возвращает -1, если предикат никогда не дает truthy значение.