50
var set = [{"color":"blue"},{"color":"green"},{"color":"red"},{"color":"green"}];

I'd like to be able to do something like a db call, set.find({"color":"green"}) and have it return an array full of objects that contain that property.

3
  • 1
    Already answered in stackoverflow.com/questions/1820593/search-a-javascript-object Commented Jun 4, 2011 at 15:19
  • 1
    That example doesn't return the whole object, does it? Commented Jun 4, 2011 at 15:25
  • 1
    This has nothing to do with jQuery, so you should remove that tag. It is a purely JavaScript question. Commented Jun 4, 2011 at 15:27

5 Answers 5

91

Using Array#filter, for this particular case the code would look like

var results = set.filter(function (entry) { return entry.color === "green"; });

Array#filter is not implemented in some older browsers, so see the linked article for a backward compatibility shim, or better yet get a full-fledged ES5 shim.

For the more general case, it's just a matter of extending this idea:

function findByMatchingProperties(set, properties) {
    return set.filter(function (entry) {
        return Object.keys(properties).every(function (key) {
            return entry[key] === properties[key];
        });
    });
}

var results = findByMatchingProperties(set, { color: "green" });

Again, I am using ECMAScript 5 methods Object.keys and Array#every, so use an ES5 shim. (The code is doable without an ES5 shim but uses manual loops and is much less fun to write and read.)

Sign up to request clarification or add additional context in comments.

6 Comments

Even weirder that you're including the jQuery tag then.
what would this look like as a method? set.find({color:"green"}), basically looking to create faux db functionality.
@float, are you looking to add this method to all arrays, or just your custom objects, or...? If the former, what do you expect it to do for an array of integers?
it could just be on a user object, so findUser() finds their object in the user array - doesn't need to be a general method.
Well you're welcome to post a followup question on how methods work in JavaScript, but just to get you started, var users = { users: [], findUser: function (properties) { return findByMatchingProperties(this.users, properties); } };
|
5

Using arrow functions with an implied return and concise body:

const results = set.filter(entry => entry.color === "green");

Another example passing in a search variable:

const searchString = 'green'; 
const results = set.filter(entry => entry.color === `${searchString}`);

Read more about arrow functions on MDN

2 Comments

howdy, why do you use === rather than ==, in this particular case? thanks!
I typically use the strict equality operator === out of habit to try and avoid pitfalls that can happen with type conversions when using the equality operator ==. In my example case either would give the same result, but I try to stick to === unless there is a good case to not use it.
3

I have used map function from jquery and I am getting selected index by passing searched key value so by using that index we will get required object from array.

var mydata = [{ name: "Ram", Id: 1 }, { name: "Shyam", Id: 2 }, { name: "Akhil", Id: 3 }];

searchKey = 2

var mydata = [{ name: "Ram", Id: 1 }, { name: "Shyam", Id: 2 }, { name: "Akhil", Id: 3 }];

searchKey = 2

var selectedData = mydata[mydata.map(function (item) { return item.Id; }).indexOf(searchKey)];

console.log(selectedData)

var selectedData = mydata[mydata.map(function (item) { return item.Id; }).indexOf(searchKey)];

console.log(selectedData)

output
{ name: "Shyam", Id: 2 }

Note: if you want to pass search key as object then
searchKey = { Id: 2 };

mydata[mydata.map(function (item) { return item.Id; }).indexOf(searchKey.Id)];

output
{ name: "Shyam", Id: 2 }

1 Comment

jQuery's map function is exactly what I needed. Your code snippet is great and was the first one to suggest using map, so I up-voted yours.
1

Since you've included the jQuery tag, here's one way to do it using jQuery's map:

var results = $.map( set, function(e,i){
  if( e.color === 'green' ) return e; 
});

The documentation states that you need to return null to remove the element from the array, but apparently this is false, as shown by the jsFiddle in the comments; returning nothing (i.e. returning undefined) works just as well.

6 Comments

This will return [undefined, { color: "green" }, undefined, undefined].
@Ken Redler, I stand corrected. The documentation for $.map says it will only remove the element if you return null, but I guess it recognizes undefined as well. Still, I think usually you'd want to use $.grep for this.
@Domenic, I do see that point about null in the documentation, but as far as I know it's always worked with the undefined of a function that has no return in some cases. I.e., omitting the return statement entirely has always resulted in an array with zero elements, if I recall correctly.
@Ken Redler, yup, I believe you; I just think it sucks that their documentation doesn't mention this.
@Domenic, I agree. I've submitted a documentation update suggestion to the jQuery team.
|
0

I went with a different approach that I found to be a bit easier.

function isObjEqual(a, b) {
    const x = JSON.stringify(a);
    const y = JSON.stringify(b);
  
    return x === y;
  }

// Example 1
const set = [{"color":"blue"},{"color":"green"},{"color":"red"},{"color":"green"}];
const findObj1 = {"color":"green"};
const arr1 = set.filter((objInArr) => isObjEqual(objInArr, findObj1));
console.log(arr1) // [ { color: 'green' }, { color: 'green' } ]

  // Example 2
const list = [{
    "label": "Option 2",
    "value": "option2"
  },
  {
    "label": "Option 3",
    "value": "option3"
  },
  {
    "label": "Option 2",
    "value": "option2"
  }
];

const findObj2 = {
  "label": "Option 2",
  "value": "option2"
}

const newList = list.filter((objInArr) => isObjEqual(objInArr, findObj2));
console.log(newList) //[ { label: 'Option 2', value: 'option2' }, { label: 'Option 2', value: 'option2' } ]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.