680

I know similar questions have been asked before, but this one is a little different. I have an array of unnamed objects, which contain an array of named objects, and I need to get the object where "name" is "string 1". Here is an example array.

var array = [
 { name:"string 1", value:"this", other: "that" },
 { name:"string 2", value:"this", other: "that" }
];

Update: I should have said this earlier, but once I find it, I want to replace it with an edited object.

dreftymac
32.6k27 gold badges125 silver badges191 bronze badges
asked Sep 17, 2012 at 15:19
1
  • 7
    If you know where it is, you can just use array[0]['name'] Commented Sep 17, 2012 at 15:21

20 Answers 20

1430

Finding the array element:

let arr = [
 { name:"string 1", value:"this", other: "that" },
 { name:"string 2", value:"this", other: "that" }
];
let obj = arr.find(o => o.name === 'string 1');
console.log(obj);


Replacing the array element:

let arr = [
 { name:"string 1", value:"this", other: "that" },
 { name:"string 2", value:"this", other: "that" }
];
let obj = arr.find((o, i) => {
 if (o.name === 'string 1') {
 arr[i] = { name: 'new string', value: 'this', other: 'that' };
 return true; // stop searching
 }
});
console.log(arr);

answered Sep 17, 2012 at 15:24
Sign up to request clarification or add additional context in comments.

12 Comments

For your second example, you should take arr in as the third argument to the callback function. That's what it's meant for.
@AaditMShah I wonder what the point of that is. The arr variable is already available in the outer scope.
Two reasons. First, it might not always be the case the the arr variable is available in the outer scope. Second, it's faster because it's a local variable.
@AaditMShah If there is no variable, then yes, that third argument can be useful. But since we have the variable in this case, there is no need for it. Regarding the second point, it’s not faster in practice. That 1-microsecond improvement isn’t even worth talking about, let alone creating code for it, IMHO.
@nishant No need. The find method invokes the function for every array element automatically, until a truthy value is returned. So if the function doesn’t return anything, the return value is undefined, which is not truthy, so the function is invoked for the next element normally.
|
326

You can loop over the array and test for that property:

function search(nameKey, myArray){
 for (let i=0; i < myArray.length; i++) {
 if (myArray[i].name === nameKey) {
 return myArray[i];
 }
 }
}
const array = [
 { name:"string 1", value:"this", other: "that" },
 { name:"string 2", value:"this", other: "that" }
];
const resultObject = search("string 1", array);
console.log(resultObject)

Christian
3351 gold badge7 silver badges19 bronze badges
answered Sep 17, 2012 at 15:23

3 Comments

change the function to this search(nameKey, prop, myArray) and the if clause to this if (myArray[i][prop]=== nameKey) { and you search for any properties inside the object
also there is a tiny utility for this called super-array
in case of integer value, use ==
227

In ES6 you can use Array.prototype.find(predicate, thisArg?) like so:

array.find(x => x.name === 'string 1')

http://exploringjs.com/es6/ch_arrays.html#_searching-for-array-elements https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/find

To then replace said object (and use another cool ES6 method fill) you could do something like:

let obj = array.find(x => x.name === 'string 1');
let index = array.indexOf(obj);
array.fill(obj.name='some new string', index, index++);
answered Jul 21, 2016 at 9:34

5 Comments

I happened to find this answer when searching for how to use find in an Angular2 template to set an attribute. It ends up this post has a good combination of ES6 find with pipes... stackoverflow.com/questions/35986017/…
If it is just one value, here, you can also shorthand it to: array.find(x => x.name === "string 1").name = "some new string";
thank you si.!!!! was able to use this code to literally find something in the array and then get it out the name and use the variable... I will post my answer below
There is already findIndex method available that returns the index instead of the object which saves you from using indexOf again.
I was only able to make this work using ==, not ===
89

As per ECMAScript 6, you can use the findIndex function.

array[array.findIndex(x => x.name == 'string 1')]
Paul Roub
36.5k27 gold badges88 silver badges95 bronze badges
answered May 18, 2017 at 12:56

3 Comments

findIndex is the right solution. certainly not foreach inside foreach. this should be accepted answer
This solution works well and is concise and clean!
With ES6 you'd have .find() which directly returns the element. Fetching the index with .findIndex() and then fetching the element by the index is not needed.
87

Considering you have following snippet:

var array = [
 { name:"string 1", value:"this", other: "that" },
 { name:"string 2", value:"this", other: "that" }
];

You can use the following function to search for items

const search = what => array.find(element => element.name === what);

And you can check whether the item was found or not.

const found = search("string1");
if (found) {
 console.log(found.value, found.other);
} else {
 console.log('No result found');
}
answered Feb 10, 2018 at 8:52

3 Comments

const serached = search("string 1"); if (serached) { console.log(serached.name, serached.value, serached.other); } else { console.log('No result found'); }
Even BETTER solution: const search = (what, arr) => arr.find(element => element[what.split(':')[0]] === what.split(':')[1]); const serached = search("value:string 1",array); if (serached) { console.log(serached.name, serached.value, serached.other); } else { console.log('No result found'); }
@martti Thanks for pointing that out. Edited the anaswer
72
var array = [
 { name:"string 1", value:"this", other: "that" },
 { name:"string 2", value:"this", other: "that" }
];
var foundValue = array.filter(obj=>obj.name==='string 1');
console.log(foundValue);
answered Dec 13, 2017 at 10:30

5 Comments

'find' is a better option than 'filter' to find a specific object
why is find a better option, and able to help find specific object?? The difference is it gets the first object vs returning all results. find doesn't tell u how many result matches the string. on the contrary filter supports IE and find doesn't
The problem with filter is that it returns an array, not the value!
I was looking for this kind of answer instead of the top ones. tnx :)
The find() method returns the first value that matches from the collection. Once it matches the value in findings, it will not check the remaining values in the array collection. The filter() method returns the matched values in an array from the collection.
28

With a foreach:

let itemYouWant = null;
array.forEach((item) => {
 if (item.name === 'string 1') {
 itemYouWant = item;
 }
});
console.log(itemYouWant);

Or even better with a map:

const itemYouWant = array.map((item) => {
 if (item.name === 'string 1') {
 return item;
 }
 return null;
});
console.log(itemYouWant);
answered May 4, 2017 at 9:19

2 Comments

you can't return from foreach loop, it will iterate for all items, irrespective of any condition you put.
@ShashankGaurav Your right I was using my example in a function. So I updated my answer. Thnx for the feedback!
24

Either use a simple for-loop:

var result = null;
for (var i = 0; i < array.length; i++) { 
 if (array[i].name === "string 1") { 
 result = array[i];
 break;
 } 
}

Or if you can, that is, if your browser supports it, use Array.filter, which is much more terse:

var result = array.filter(function (obj) {
 return obj.name === "string 1";
})[0];
answered Sep 17, 2012 at 15:24

3 Comments

When the obj is returned, how do I get its position in the original array?
@VedranMaricevic. Using array.fill()
When no ES6 support (such as using Google Tag Manager), for loops solve the problem. :)
22

with underscore.js use the findWhere method:

var array = [
 { name:"string 1", value:"this", other: "that" },
 { name:"string 2", value:"this", other: "that" }
];
var result = _.findWhere(array, {name: 'string 1'});
console.log(result.name);

See this in JSFIDDLE

answered Jul 31, 2015 at 14:16

2 Comments

If you need to know the array index (not just the matching object) you can mix _.findWhere() with _.indexOf() like so: var index = _.indexOf(array, _.findWhere(array, {name: 'string 1'}));
@James Seems like a waste, as that will have to iterate through the array twice. Plus, you're not gaining any code clarity from underscore at that point. Better to just write your own well-names function if you're resorting to that.
20

One line answer. You can use filter function to get result.

var array = [
 { name:"string 1", value:"this", other: "that" },
 { name:"string 2", value:"this", other: "that" }
];
console.log(array.filter(function(arr){return arr.name == 'string 1'})[0]);

answered Nov 9, 2017 at 4:43

Comments

15

New answer

I added the prop as a parameter, to make it more general and reusable

/**
 * Represents a search trough an array.
 * @function search
 * @param {Array} array - The array you wanna search trough
 * @param {string} key - The key to search for
 * @param {string} [prop] - The property name to find it in
 */
function search(array, key, prop){
 // Optional, but fallback to key['name'] if not selected
 prop = (typeof prop === 'undefined') ? 'name' : prop; 
 for (var i=0; i < array.length; i++) {
 if (array[i][prop] === key) {
 return array[i];
 }
 }
}

Usage:

var array = [
 { 
 name:'string 1', 
 value:'this', 
 other: 'that' 
 },
 { 
 name:'string 2', 
 value:'this', 
 other: 'that' 
 }
];
search(array, 'string 1');
// or for other cases where the prop isn't 'name'
// ex: prop name id
search(array, 'string 1', 'id');

Mocha test:

var assert = require('chai').assert;
describe('Search', function() {
 var testArray = [
 { 
 name: 'string 1', 
 value: 'this', 
 other: 'that' 
 },
 { 
 name: 'string 2', 
 value: 'new', 
 other: 'that' 
 }
 ];
 it('should return the object that match the search', function () {
 var name1 = search(testArray, 'string 1');
 var name2 = search(testArray, 'string 2');
 assert.equal(name1, testArray[0]);
 assert.equal(name2, testArray[1]);
 var value1 = search(testArray, 'this', 'value');
 var value2 = search(testArray, 'new', 'value');
 assert.equal(value1, testArray[0]);
 assert.equal(value2, testArray[1]);
 });
 it('should return undefined becuase non of the objects in the array have that value', function () {
 var findNonExistingObj = search(testArray, 'string 3');
 assert.equal(findNonExistingObj, undefined);
 });
 it('should return undefined becuase our array of objects dont have ids', function () {
 var findById = search(testArray, 'string 1', 'id');
 assert.equal(findById, undefined);
 });
});

test results:

Search
 ✓ should return the object that match the search
 ✓ should return undefined becuase non of the objects in the array have that value
 ✓ should return undefined becuase our array of objects dont have ids
 3 passing (12ms)

Old answer - removed due to bad practices

if you wanna know more why it's bad practice then see this article:

Why is extending native objects a bad practice?

(削除) Prototype version of doing an array search:

Array.prototype.search = function(key, prop){
 for (var i=0; i < this.length; i++) {
 if (this[i][prop] === key) {
 return this[i];
 }
 }
}

Usage:

var array = [
 { name:'string 1', value:'this', other: 'that' },
 { name:'string 2', value:'this', other: 'that' }
];
array.search('string 1', 'name');

(削除ここまで)

answered Oct 13, 2015 at 8:05

8 Comments

You should never modify the prototype of a native object. Have a google around for why this is bad, there's plenty of articles and stackoverflow questions. The answer in this question gives a good reason (stackoverflow.com/questions/3010840/…)
Worked great for me so far, but it might be an anti pattern
It does work but yeah it's an anti-pattern and bad practice
@silverlight513 also added mocha tests and results
+1 for adding tests, they're always something worth adding. I'd have to say though that Šime Vidas's use of filter seems to be a much cleaner way of looping through an array to find an object (imo).
|
10

You can do it with a simple loop:

var obj = null; 
for (var i = 0; i < array.length; i++) {
 if (array[i].name == "string 1") {
 obj = array[i];
 break;
 }
}
answered Sep 17, 2012 at 15:21

4 Comments

What is the empty object good for?
@Bergi It depends on what is the purpose of the code. How about null then?
Makes more sense to me, thanks. Just undefined would be Ok as well imho...
@Bergi Maybe null is more depictive for not found element.
4

Another way (to aid @NullUserException and @Wexoni's comments) is to retrieve the object's index in the array and then go from there:

var index = array.map(function(obj){ return obj.name; }).indexOf('name-I-am-looking-for');
// Then we can access it to do whatever we want
array[index] = {name: 'newName', value: 'that', other: 'rocks'};
answered Jun 9, 2016 at 20:53

Comments

3

Similar to previous answers I used the following:

 Array.prototype.getIemtByParam = function(paramPair) {
 var key = Object.keys(paramPair)[0];
 return this.find(function(item){return ((item[key] == paramPair[key]) ? true: false)});
 }

usage:

myArray.getIemtByParam(
 {name: 'Sasha'}
);
narendra-choudhary
4,8664 gold badges43 silver badges61 bronze badges
answered Nov 20, 2015 at 11:35

Comments

2

Here is the solution for search and replace

function searchAndUpdate(name,replace){
 var obj = array.filter(function ( obj ) {
 return obj.name === name;
 })[0];
 obj.name = replace;
}
searchAndUpdate("string 2","New String 2");
answered Jun 17, 2014 at 12:05

Comments

2

Are you looking for generic Search(Filter) across the item in the object list without specifying the item key

Input

var productList = [{category: 'Sporting Goods', price: '49ドル.99', stocked: true, name: 'Football'}, {category: 'Sporting Goods', price: '9ドル.99', stocked: true, name: 'Baseball'}, {category: 'Sporting Goods', price: '29ドル.99', stocked: false, name: 'Basketball'}, {category: 'Electronics', price: '99ドル.99', stocked: true, name: 'iPod Touch'}, {category: 'Electronics', price: '399ドル.99', stocked: false, name: 'iPhone 5'}, {category: 'Electronics', price: '199ドル.99', stocked: true, name: 'Nexus 7'}]
function customFilter(objList, text){
if(undefined === text || text === '' ) return objList;
return objList.filter(product => {
 let flag;
 for(let prop in product){
 flag = false;
 flag = product[prop].toString().indexOf(text) > -1;
 if(flag)
 break;
 }
return flag;
});}

Execute

customFilter(productList, '9ドル');

enter image description here

answered Mar 19, 2017 at 19:56

2 Comments

this works fine. how do I make it work for nested object ?
0

if you are using jQuery try $.grep().

http://api.jquery.com/jquery.grep/

answered May 27, 2016 at 18:16

Comments

0

You can use query-objects from npm. You can search an array of objects using filters.

const queryable = require('query-objects');
const users = [
 {
 firstName: 'George',
 lastName: 'Eracleous',
 age: 28
 },
 {
 firstName: 'Erica',
 lastName: 'Archer',
 age: 50
 },
 {
 firstName: 'Leo',
 lastName: 'Andrews',
 age: 20
 }
];
const filters = [
 {
 field: 'age',
 value: 30,
 operator: 'lt'
 },
 {
 field: 'firstName',
 value: 'Erica',
 operator: 'equals'
 }
];
// Filter all users that are less than 30 years old AND their first name is Erica
const res = queryable(users).and(filters);
// Filter all users that are less than 30 years old OR their first name is Erica
const res = queryable(users).or(filters);
answered Aug 5, 2016 at 9:41

Comments

-1
function getValue(){
 for(var i = 0 ; i< array.length; i++){
 var obj = array[i];
 var arr = array["types"];
 for(var j = 0; j<arr.length;j++ ){
 if(arr[j] == "value"){
 return obj;
 }
 }
 }
}
answered Dec 12, 2014 at 12:07

Comments

-1

This answer is good for typescript / Angular 2, 4, 5+

I got this answer with the help of @rujmah answer above. His answer brings in the array count... and then find's the value and replaces it with another value...

What this answer does is simply grabs the array name that might be set in another variable via another module / component... in this case the array I build had a css name of stay-dates. So what this does is extract that name and then allows me to set it to another variable and use it like so. In my case it was an html css class.

let obj = this.highlightDays.find(x => x.css); let index = this.highlightDays.indexOf(obj); console.log('here we see what hightlightdays is ', obj.css); let dayCss = obj.css;

answered Jul 27, 2017 at 16:08

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.