Jquery, как найти объект по атрибуту в массиве - PullRequest
62 голосов
/ 07 апреля 2011

Учитывая, что у меня есть массив "целевых" объектов:

//array of purpose objects:
var purposeObjects = [
    {purpose: "daily"},
    {purpose: "weekly"},
    {purpose: "monthly"}
];

(для простоты я опускаю другие атрибуты)

Теперь я хочу иметь метод, который возвращает конкретныйобъектов, если найдено подходящее имя цели.

Это не работает:

function findPurpose(purposeName){
    return $.grep(purposeObjects, function(){
      return this.purpose == purposeName;
    });
};

findPurpose("daily");

, но фактически возвращает пустой массив:

[]

Я использую JQuery 1.5.2.Я также пытался с $ .each (), но безуспешно.По-видимому, большинство методов JQuery предназначены для использования с элементами DOM (например, filter().

. Есть идеи, как этого добиться?

Ответы [ 11 ]

78 голосов
/ 02 апреля 2013

ES6

    array.find((o) => { return o[propertyName] === propertyValue })

Подробнее о методе find здесь .

ES5

var findPurpose = function(purposeName) {
    for (var i = 0, len = purposeObjects.length; i < len; i++) {
        if (purposeObjects[i].purpose === purposeName)
            return purposeObjects[i]; // Return as soon as the object is found
    }
    return null; // The object was not found
}

Примечание

jQuery $ .grep (или другая функция фильтрации) не является оптимальным решением.

Функция $.grep будет проходить через все элементы массива, даже еслиискомый объект уже был найден во время цикла.Из документации jQuery grep:

Метод $ .grep () удаляет элементы из массива по мере необходимости, чтобы все оставшиеся элементы проходили предоставленный тест.Тест - это функция, которой передается элемент массива и индекс элемента в массиве.Только если тест вернет true, элемент будет в массиве результатов.

37 голосов
/ 07 апреля 2011

Вы должны передать ссылку на элемент в функции grep:

function findPurpose(purposeName){
    return $.grep(purposeObjects, function(item){
      return item.purpose == purposeName;
    });
};

Пример

29 голосов
/ 03 октября 2013

Я лично использую более общую функцию, которая работает для любого свойства любого массива:

function lookup(array, prop, value) {
    for (var i = 0, len = array.length; i < len; i++)
        if (array[i] && array[i][prop] === value) return array[i];
}

Вы просто называете это так:

lookup(purposeObjects, "purpose", "daily");
26 голосов
/ 07 апреля 2011

Ошибка состояла в том, что вы не можете использовать this в grep, но вы должны использовать ссылку на элемент. Это работает:

function findPurpose(purposeName){
    return $.grep(purposeObjects, function(n, i){
      return n.purpose == purposeName;
    });
};

findPurpose("daily");

возвращает:

[Object { purpose="daily"}]
5 голосов
/ 01 июля 2015

Используйте функцию findWhere для Underscore.js (http://underscorejs.org/#findWhere):

var purposeObjects = [
    {purpose: "daily"},
    {purpose: "weekly"},
    {purpose: "monthly"}
];

var daily = _.findWhere(purposeObjects, {purpose: 'daily'});

daily будет равно:

{"purpose":"daily"}

Вот скрипка: http://jsfiddle.net/spencerw/oqbgc21x/

Чтобы вернуть более одного (, если у вас было больше в вашем массиве), вы можете использовать _.where(...)

4 голосов
/ 23 ноября 2015

Лучший, самый быстрый способ -

function arrayLookup(array, prop, val) {
    for (var i = 0, len = array.length; i < len; i++) {
        if (array[i].hasOwnProperty(prop) && array[i][prop] === val) {
            return array[i];
        }
    }
    return null;
}
3 голосов
/ 09 апреля 2016

Если ваш массив на самом деле представляет собой набор объектов JQuery, как насчет простого использования метода .filter () ?

purposeObjects.filter('[purpose="daily"]')
1 голос
/ 09 марта 2016

Еще одно решение:

function firstOrNull(array, expr) {
  for (var i = 0; i < array.length; i++) {
    if (expr(array[i]))
      return array[i];
    }
  return null;
}

Использование: firstOrNull([{ a: 1, b: 2 }, { a: 3, b: 3 }], function(item) { return item.a === 3; });

Эта функция не выполняется для каждого элемента массива (это полезно для больших массивов)

0 голосов
/ 06 мая 2019

скопировано из кода Array.prototype.find для polyfill Array.find и добавило массив в качестве первого параметра.

Вы можете передать поисковый термин как функцию предиката

// Example
var listOfObjects = [{key: "1", value: "one"}, {key: "2", value: "two"}]
var result = findInArray(listOfObjects, function(element) {
  return element.key == "1";
});
console.log(result);

// the function you want
function findInArray(listOfObjects, predicate) {
      if (listOfObjects == null) {
        throw new TypeError('listOfObjects is null or not defined');
      }

      var o = Object(listOfObjects);

      var len = o.length >>> 0;

      if (typeof predicate !== 'function') {
        throw new TypeError('predicate must be a function');
      }

      var thisArg = arguments[1];

      var k = 0;

      while (k < len) {
        var kValue = o[k];
        if (predicate.call(thisArg, kValue, k, o)) {
          return kValue;
        }
        k++;
      }

      return undefined;
}
0 голосов
/ 22 сентября 2017

Javascript имеет функцию только для этого: Array.prototype.find .Как пример

function isBigEnough(element) {
  return element >= 15;
}

[12, 5, 8, 130, 44].find(isBigEnough); // 130

Нетрудно расширить функцию обратного вызова для функции.Однако это не совместимо с IE (и частично с Edge).Для полного списка посмотрите на Совместимость браузера

...