Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get an object from array which contains a specific value

I am trying to search through an array of objects using Underscore.js, but I can't seem to target the one I want.

console.log(_.findWhere(response.data, { TaskCategory: { TaskCategoryId: $routeParams.TaskCategory } }));

However, this is returning undefined $routeParams.TaskCategory is equal to 301

This is an example of the objects inside the array I am searching. This data is represented by data.response

[{
    "TaskCategory": {
        "TaskCategoryId": 201,
        "TaskName": "TaskName"
    },
    "TaskCount": 1,
    "Tasks": [{
        "EventTypeId": 201,
        "EventName": "Event Driver",
        "EventDate": "0001-01-01T00:00:00",
        "EventId": "00000000-0000-0000-0000-000000000000",
    }]
},
{
    "TaskCategory": {
        "TaskCategoryId": 301,
        "TaskName": "TaskName"
    },
    "TaskCount": 1,
    "Tasks": [{
        "EventTypeId": 201,
        "EventName": "Event Driver",
        "EventDate": "0001-01-01T00:00:00",
        "EventId": "00000000-0000-0000-0000-000000000000",
    }]
}]

So I want the second object in that array using the TaskCategory.TaskCategoryId, is it possible to get it using Underscore?

like image 221
Neil Avatar asked Oct 21 '13 17:10

Neil


People also ask

How do you find a specific object in an array?

Answer: Use the find() Method You can simply use the find() method to find an object by a property value in an array of objects in JavaScript. The find() method returns the first element in the given array that satisfies the provided testing function. If no values satisfy the testing function, undefined is returned.

How do you check if an array contains a specific item?

The simplest and fastest way to check if an item is present in an array is by using the Array. indexOf() method. This method searches the array for the given item and returns its index. If no item is found, it returns -1.


2 Answers

Use _.find instead of findWhere:

console.log(_.find(response.data, function(item) {
    return item.TaskCategory.TaskCategoryId == $routeParams.TaskCategory; 
}));

They are similar, but findWhere is designed for special cases where you want to match key-value pairs (not useful in your scenario as it involves nested objects). Find is more general-use, because it lets you provide a function as the predicate.

like image 71
McGarnagle Avatar answered Oct 19 '22 18:10

McGarnagle


The source of _.findWhere / _.where is as follows

_.where = function(obj, attrs, first) {
  if (_.isEmpty(attrs)) return first ? void 0 : [];
  return _[first ? 'find' : 'filter'](obj, function(value) {
    for (var key in attrs) {
      if (attrs[key] !== value[key]) return false;
    }
    return true;
  });
};

_.findWhere = function(obj, attrs) {
  return _.where(obj, attrs, true);
};

As you can see, it performs strict equality rather than deep equality. If you want a deep searching where, this would suffice (untested, unoptimized):

_.whereDeep = function(obj, attrs, first) {
  if (_.isEmpty(attrs)) return first ? void 0 : [];
  return _[first ? 'find' : 'filter'](obj, function(value) {
    for (var key in attrs) {
      if (attrs[key] !== value[key] || !(_.isObject(attrs[key]) && _.whereDeep([value[key]], attrs[key], true))) return false;
    }
    return true;
  });
};

_.findWhereDeep = function(obj, attrs) {
  return _.whereDeep(obj, attrs, true);
};

And you would be able to use your code, almost unchanged

_.findWhereDeep(response.data, { TaskCategory: { TaskCategoryId: $routeParams.TaskCategory } });
like image 7
forivall Avatar answered Oct 19 '22 16:10

forivall