JQuery how to find an object by attribute in an array

Given that I have an array of targets:

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

(for simplicity, I omit other attributes)

Now I want to have a method that returns a specific object if a suitable name is found.

This does not work:

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

but actually returns an empty array:

 [] 

I am using jQuery 1.5.2. I also tried with $ .each (), but no luck. Apparently, most jQuery methods are designed to be used with DOM elements (e.g. filter() .

Any ideas on how to achieve this?

+62
jquery collections filter traversal
Apr 07 2018-11-11T00:
source share
11 answers

The error was that you cannot use this in grep, but you should use an element reference. It works:

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

returns:

 [Object { purpose="daily"}] 
+26
Apr 07 2018-11-11T00:
source share

ES6

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

Read 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 } 



The note

jQuery $ .grep (or another filtering function) is not an optimal solution.

The $.grep function will $.grep over all elements of the array, even if the desired object was already found during the loop. From the jQuery grep documentation:

The $ .grep () method removes elements from the array as necessary so that all remaining elements pass the provided test. A test is a function that passes an element of an array and the index of an element in an array. Only if the test returns true, the element will be in the array of results.

+78
Apr 02 '13 at 15:10
source share

you should pass the element reference in the grep function:

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

Example

+37
Apr 7 2018-11-11T00:
source share

I personally use a more general 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 simply call it like this:

 lookup(purposeObjects, "purpose", "daily"); 
+29
Oct 03 '13 at 8:28
source share

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 will be equal to:

 {"purpose":"daily"} 

Here's the script: http://jsfiddle.net/spencerw/oqbgc21x/

To return more than one (if there was more in your array), you can use _.where(...)

+5
Jul 01 '15 at 19:38
source share

The best, fastest way

 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; } 
+4
Nov 23 '15 at 12:46
source share

If your array is actually a collection of jQuery objects, just using a method . filter () ?

 purposeObjects.filter('[purpose="daily"]') 
+3
Apr 09 '16 at 11:24
source share

Another solution:

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

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

This function is not executed for each element of the array (it is important for large arrays)

+1
Mar 09 '16 at 11:59 on
source share

I created a util service for my angular application. It has two functions that are used very often.

For example, you have an object.

First get the value from the object recursively without throwing an undefined error.

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

The second array of filters based on

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

Find an object from an array using 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; }}); 

To resolve the current issue. enter UtilService and call

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

Or more advanced

 UtilService.arrayPropFilter(purposeArray,'purpose.nestedProp1.nestedProp2','daily'); 
0
Aug 07 '16 at 7:38
source share

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

 function isBigEnough(element) { return element >= 15; } [12, 5, 8, 130, 44].find(isBigEnough); // 130 

It is not difficult to extend the function callback. However, this is incompatible with IE (and partially with Edge). A complete list of browser compatibility

0
Sep 22 '17 at 14:49
source share

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

You can pass a search term as a predicate

 // 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
May 6 '19 at 19:18
source share



All Articles