web-dev-qa-db-fra.com

Récupère un objet du tableau qui contient une valeur spécifique

J'essaie de rechercher dans un tableau d'objets en utilisant Underscore.js, mais je n'arrive pas à cibler celui que je veux.

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

Cependant, cela renvoie undefined$routeParams.TaskCategory est égal à 301

Ceci est un exemple des objets à l'intérieur du tableau que je recherche. Ces données sont représentées par 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",
    }]
}]

Je veux donc le deuxième objet de ce tableau en utilisant le TaskCategory.TaskCategoryId, est-il possible de l'obtenir en utilisant Underscore?

31
Neil

Utilisation _.find au lieu de findWhere:

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

Ils sont similaires, mais findWhere est conçu pour les cas spéciaux où vous souhaitez faire correspondre des paires clé-valeur (pas utile dans votre scénario car il implique des objets imbriqués). Find est un usage plus général, car il vous permet de fournir une fonction comme prédicat.

56
McGarnagle

La source de _.findWhere/_.where est comme suit

_.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);
};

Comme vous pouvez le voir, il effectue une égalité stricte plutôt qu'une égalité profonde. Si vous voulez une recherche approfondie où, cela suffira (non testé, non optimisé):

_.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);
};

Et vous seriez en mesure d'utiliser votre code, presque inchangé

_.findWhereDeep(response.data, { TaskCategory: { TaskCategoryId: $routeParams.TaskCategory } });
7
forivall