Jquery how to find an Object by attribute in an Array

匆匆过客 提交于 2019-11-27 11:25:15

ES6

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

More about the find method here.

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
}

Note

jQuery $.grep (or other filtering function) is not the optimal solution.

The $.grep function will loop through all the elements of the array, even if the searched object has been already found during the loop. From jQuery grep documentation :

The $.grep() method removes items from an array as necessary so that all remaining items pass a provided test. The test is a function that is passed an array item and the index of the item within the array. Only if the test returns true will the item be in the result array.

you should pass reference on item in grep function:

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

Example

I personally use a more generic function that works for any property of any array:

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

You just call it like this:

lookup(purposeObjects, "purpose", "daily");

The error was that you cannot use this in the grep, but you must use a reference to the element. This works:

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

findPurpose("daily");

returns:

[Object { purpose="daily"}]

Use the Underscore.js findWhere function (http://underscorejs.org/#findWhere):

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

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

daily would equal:

{"purpose":"daily"}

Here's a fiddle: http://jsfiddle.net/spencerw/oqbgc21x/

To return more than one (if you had more in your array) you could use _.where(...)

Best, Fastest way is

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

If your array is actually a set of JQuery objects, what about simply using the .filter() method ?

purposeObjects.filter('[purpose="daily"]')

One more solution:

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

Using: firstOrNull([{ a: 1, b: 2 }, { a: 3, b: 3 }], function(item) { return item.a === 3; });

This function don't executes for each element from the array (it's valuable for large arrays)

I have created a util service for my angular application. It have two function which use very often.

For example you have object.

First getting value from object recursively without throwing undefined error.

{prop: { nestedProp1: {nestedProp2: somevalue}}}; get nestedProp2 2 without undefined checks.

Second filter array on basis

[{prop: { nestedProp1: {nestedProp2: somevalue1}}}, {prop: { nestedProp1: {nestedProp2: somevalue2}}}];

Find object from array with nestedProp2=somevalue2

app.service('UtilService', function(httpService) {
this.mapStringKeyVal = function(map, field) {
    var lastIdentifiedVal = null;
    var parentVal = map;
    field.split('.').forEach(function(val){
        if(parentVal[val]){
            lastIdentifiedVal = parentVal[val]; 
            parentVal = parentVal[val]; 
        }
    });
    return lastIdentifiedVal;
}


this.arrayPropFilter = function(array, field,value) {
    var lastIdentifiedVal = null;
    var mapStringKeyVal = this.mapStringKeyVal;
    array.forEach(function(arrayItem){
        var valueFound = mapStringKeyVal(arrayItem,field);
        if(!lastIdentifiedVal  && valueFound && valueFound==value){
            lastIdentifiedVal = arrayItem;
        }
    });
    return lastIdentifiedVal;
}});

For solution for current question. inject UtilService and call,

UtilService.arrayPropFilter(purposeArray,'purpose','daily');

Or more advanced

UtilService.arrayPropFilter(purposeArray,'purpose.nestedProp1.nestedProp2','daily');

Javascript has a function just for that: Array.prototype.find. As example

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

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

It not difficult to extends the callback to a function. However this is not compatible with IE (and partially with Edge). For a full list look at the Browser Compatibility

copied from polyfill Array.prototype.find code of Array.find, and added the array as first parameter.

you can pass the search term as predicate function

// 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;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!