fancy
fancy

Reputation: 51383

Finding matching objects in an array of objects?

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.

Upvotes: 50

Views: 133152

Answers (5)

Ballpin
Ballpin

Reputation: 227

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

Upvotes: 0

jhovanec
jhovanec

Reputation: 866

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

Upvotes: 5

Rambabu Bommisetti
Rambabu Bommisetti

Reputation: 137

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 }

Upvotes: 3

Ken Redler
Ken Redler

Reputation: 23943

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.

Upvotes: 1

Domenic
Domenic

Reputation: 112817

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.)

Upvotes: 91

Related Questions