Get JavaScript object from array of objects by value of property

JavascriptArrays

Javascript Problem Overview


Let's say I have an array of four objects:

var jsObjects = [
   {a: 1, b: 2}, 
   {a: 3, b: 4}, 
   {a: 5, b: 6}, 
   {a: 7, b: 8}
];

Is there a way that I can get the third object ({a: 5, b: 6}) by the value of the property b for example without a for...in loop?

Javascript Solutions


Solution 1 - Javascript

Filter array of objects, which property matches value, returns array:

var result = jsObjects.filter(obj => {
  return obj.b === 6
})

See the MDN Docs on Array.prototype.filter()

const jsObjects = [
  {a: 1, b: 2}, 
  {a: 3, b: 4}, 
  {a: 5, b: 6}, 
  {a: 7, b: 8}
]

let result = jsObjects.filter(obj => {
  return obj.b === 6
})

console.log(result)

Find the value of the first element/object in the array, otherwise undefined is returned.

var result = jsObjects.find(obj => {
  return obj.b === 6
})

See the MDN Docs on Array.prototype.find()

const jsObjects = [
  {a: 1, b: 2}, 
  {a: 3, b: 4}, 
  {a: 5, b: 6}, 
  {a: 7, b: 8}
]

let result = jsObjects.find(obj => {
  return obj.b === 6
})

console.log(result)

Solution 2 - Javascript

jsObjects.find(x => x.b === 6)

From MDN:

> The find() method returns a value in the array, if an element in the array satisfies the provided testing function. Otherwise undefined is returned.


Side note: methods like find() and arrow functions are not supported by older browsers (like IE), so if you want to support these browsers, you should transpile your code using Babel.

Solution 3 - Javascript

I don't know why you are against a for loop (presumably you meant a for loop, not specifically for..in), they are fast and easy to read. Anyhow, here's some options.

For loop:

function getByValue(arr, value) {

  for (var i=0, iLen=arr.length; i<iLen; i++) {

    if (arr[i].b == value) return arr[i];
  }
}

.filter

function getByValue2(arr, value) {

  var result  = arr.filter(function(o){return o.b == value;} );

  return result? result[0] : null; // or undefined

}

.forEach

function getByValue3(arr, value) {

  var result = [];

  arr.forEach(function(o){if (o.b == value) result.push(o);} );

  return result? result[0] : null; // or undefined

}

If, on the other hand you really did mean for..in and want to find an object with any property with a value of 6, then you must use for..in unless you pass the names to check.

Example

function getByValue4(arr, value) {
  var o;

  for (var i=0, iLen=arr.length; i<iLen; i++) {
    o = arr[i];

    for (var p in o) {
      if (o.hasOwnProperty(p) && o[p] == value) {
        return o;
      }
    }
  }
}

Solution 4 - Javascript

Ways to achieve the requirement :

  1. Using Array.find() method :

const jsObject = [
   {a: 1, b: 2}, 
   {a: 3, b: 4}, 
   {a: 5, b: 6}, 
   {a: 7, b: 8}
];

const filteredResult = jsObject.find((e) => e.b == 6);

console.log(filteredResult);

  1. Using Array.filter() method :

const jsObjects = [
   {a: 1, b: 2}, 
   {a: 3, b: 4}, 
   {a: 5, b: 6}, 
   {a: 7, b: 8}
];

const filterObj = jsObjects.filter((e) => e.b == 6);

console.log(filterObj[0]);

  1. Using for...in loop :

const jsObjects = [
   {a: 1, b: 2}, 
   {a: 3, b: 4}, 
   {a: 5, b: 6}, 
   {a: 7, b: 8}
];

for (const i in jsObjects) {
  if (jsObjects[i].b == 6) {
    console.log(jsObjects[i]);
  }
}

Solution 5 - Javascript

OK, there are few ways to do that, but let's start with the simplest one and latest approach to do this, this function is called find().

Just be careful when you using find to as even IE11 dosn't support it, so it needs to be transpiled...

so you have this object as you said:

var jsObjects = [
   {a: 1, b: 2}, 
   {a: 3, b: 4}, 
   {a: 5, b: 6}, 
   {a: 7, b: 8}
];

and you can write a function and get it like this:

function filterValue(obj, key, value) {
  return obj.find(function(v){ return v[key] === value});
}

and use the function like this:

filterValue(jsObjects, "b", 6); //{a: 5, b: 6}

Also in ES6 for even shortened version:

const filterValue = (obj, key, value)=> obj.find(v => v[key] === value);

This method only return the first value which match..., for better result and browser support, you can use filter:

const filterValue = (obj, key, value)=> obj.filter(v => v[key] === value);

and we will return [{a: 5, b: 6}]...

This method will return an array instead...

You simpley use for loop as well, create a function like this:

function filteredArray(arr, key, value) {
  const newArray = [];
  for(i=0, l=arr.length; i<l; i++) {
    if(arr[i][key] === value) {
      newArray.push(arr[i]);
    }
  }
 return newArray;
}

and call it like this:

filteredArray(jsObjects, "b", 6); //[{a: 5, b: 6}]

Solution 6 - Javascript

See this documentation Array.prototype.find()

Example:

var inventory = [
    {name: 'apples', quantity: 2},
    {name: 'bananas', quantity: 0},
    {name: 'cherries', quantity: 5}
];

function findCherries(fruit) { 
    return fruit.name === 'cherries';
}

console.log(inventory.find(findCherries)); 
// { name: 'cherries', quantity: 5 }

Solution 7 - Javascript

Using underscore.js:

var foundObject = _.findWhere(jsObjects, {b: 6});

Solution 8 - Javascript

It looks like in the ECMAScript 6 proposal there are the Array methods find() and findIndex(). MDN also offers polyfills which you can include to get the functionality of these across all browsers.

find():

function isPrime(element, index, array) {
    var start = 2;
    while (start <= Math.sqrt(element)) {
        if (element % start++ < 1) return false;
    }
    return (element > 1);
}

console.log( [4, 6, 8, 12].find(isPrime) ); // undefined, not found
console.log( [4, 5, 8, 12].find(isPrime) ); // 5

findIndex():

function isPrime(element, index, array) {
    var start = 2;
    while (start <= Math.sqrt(element)) {
        if (element % start++ < 1) return false;
    }
    return (element > 1);
}

console.log( [4, 6, 8, 12].findIndex(isPrime) ); // -1, not found
console.log( [4, 6, 7, 12].findIndex(isPrime) ); // 2

Solution 9 - Javascript

If I understand correctly, you want to find the object in the array whose b property is 6?

var found;
jsObjects.some(function (obj) {
  if (obj.b === 6) {
    found = obj;
    return true;
  }
});

Or if you were using underscore:

var found = _.select(jsObjects, function (obj) {
  return obj.b === 6;
});

Solution 10 - Javascript

If you are looking for a single result, rather than an array, may I suggest reduce?

Here is a solution in plain 'ole javascript that returns a matching object if one exists, or null if not.

var result = arr.reduce(function(prev, curr) { return (curr.b === 6) ? curr : prev; }, null);

Solution 11 - Javascript

You can use it with the arrow function as well like as below :

var demoArray = [
   {name: 'apples', quantity: 2},
   {name: 'bananas', quantity: 0},
   {name: 'cherries', quantity: 5}
];

var result = demoArray.filter( obj => obj.name === 'apples')[0];
console.log(result);
// {name: 'apples', quantity: 2}

Solution 12 - Javascript

How about using _.find(collection, [predicate=_.identity], [fromIndex=0]) of lo-dash to get object from array of objects by object property value. You could do something like this:

var o = _.find(jsObjects, {'b': 6});

Arguments:

collection (Array|Object): The collection to inspect.
[predicate=_.identity] (Function): The function invoked per iteration.
[fromIndex=0] (number): The index to search from.

Returns

(*): Returns the matched element (in your case, {a: 5, b: 6}), else undefined.

In terms of performance, _.find() is faster as it only pulls the first object with property {'b': 6}, on the other hand, if suppose your array contains multiple objects with matching set of properties (key:value), then you should consider using _.filter() method. So in your case, as your array has a single object with this property, I would use _.find().

Solution 13 - Javascript

Made the best/fastest part of this answer more re-usable & clear:

function getElByPropVal(myArray, prop, val){
	for (var i = 0, length = myArray.length; i < length; i++) {
		if (myArray[i][prop] == val){
			return myArray[i];
		}
	}
}

Solution 14 - Javascript

var result = jsObjects.filter(x=> x.b === 6);

will be better, using return in filter sometimes you can't get result (I dunno why)

Solution 15 - Javascript

To get first object from array of objects by a specific property value:

function getObjectFromObjectsArrayByPropertyValue(objectsArray, propertyName, propertyValue) {
  return objectsArray.find(function (objectsArrayElement) {
    return objectsArrayElement[propertyName] == propertyValue;
  });
}

function findObject () {
  var arrayOfObjectsString = document.getElementById("arrayOfObjects").value,
      arrayOfObjects,
      propertyName = document.getElementById("propertyName").value,
      propertyValue = document.getElementById("propertyValue").value,
      preview = document.getElementById("preview"),
      searchingObject;
  
  arrayOfObjects = JSON.parse(arrayOfObjectsString);
  
  console.debug(arrayOfObjects);
  
  if(arrayOfObjects && propertyName && propertyValue) {
    searchingObject = getObjectFromObjectsArrayByPropertyValue(arrayOfObjects, propertyName, propertyValue);
    if(searchingObject) {
      preview.innerHTML = JSON.stringify(searchingObject, false, 2);
    } else {
      preview.innerHTML = "there is no object with property " + propertyName + " = " + propertyValue + " in your array of objects";
    }
  }
}

pre {
  padding: 5px;
  border-radius: 4px;
  background: #f3f2f2;
}

textarea, button {
  width: 100%
}

<fieldset>
  <legend>Input Data:</legend>
  <label>Put here your array of objects</label>
  <textarea rows="7" id="arrayOfObjects">
  [
    {"a": 1, "b": 2},
    {"a": 3, "b": 4},
    {"a": 5, "b": 6},
    {"a": 7, "b": 8, "c": 157}
  ]
  </textarea>

  <hr>

  <label>property name: </label> <input type="text" id="propertyName"  value="b"/>
  <label>property value: </label> <input type="text" id="propertyValue" value=6 />
     
</fieldset>
<hr>
<button onclick="findObject()">find object in array!</button>
<hr>
<fieldset>
  <legend>Searching Result:</legend>
  <pre id="preview">click find</pre>
</fieldset>

Solution 16 - Javascript

Using find with bind to pass specific key values to a callback function.

   function byValue(o) { 
       return o.a === this.a && o.b === this.b; 
   };   

   var result = jsObjects.find(byValue.bind({ a: 5, b: 6 }));

Solution 17 - Javascript

var jsObjects = [{a: 1, b: 2}, {a: 3, b: 4}, {a: 5, b: 6}, {a: 7, b: 8}];

to access the third object, use: jsObjects[2];
to access the third object b value, use: jsObjects[2].b;

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser765368View Question on Stackoverflow
Solution 1 - JavascriptelclanrsView Answer on Stackoverflow
Solution 2 - JavascriptMichał PerłakowskiView Answer on Stackoverflow
Solution 3 - JavascriptRobGView Answer on Stackoverflow
Solution 4 - JavascriptRohìt JíndalView Answer on Stackoverflow
Solution 5 - JavascriptAlirezaView Answer on Stackoverflow
Solution 6 - JavascriptasrulsibaoelView Answer on Stackoverflow
Solution 7 - JavascriptmaiaView Answer on Stackoverflow
Solution 8 - JavascriptAmirView Answer on Stackoverflow
Solution 9 - JavascriptnickfView Answer on Stackoverflow
Solution 10 - JavascriptSam DushayView Answer on Stackoverflow
Solution 11 - JavascriptShobhit SharmaView Answer on Stackoverflow
Solution 12 - JavascriptSimple-SolutionView Answer on Stackoverflow
Solution 13 - JavascriptAndrewView Answer on Stackoverflow
Solution 14 - JavascriptDiedView Answer on Stackoverflow
Solution 15 - JavascriptkolodiView Answer on Stackoverflow
Solution 16 - JavascriptSerjuiceView Answer on Stackoverflow
Solution 17 - JavascriptManjunathan MView Answer on Stackoverflow