首页 > 解决方案 > Mapping and filtering a nested object

问题描述

I'm trying to find all objects that contain filter with the Name of Industry and the Value of Tech. Here's my object:

const obj = [{
    "Id": 1,
    "Name": "Video Games",
    "Labels": [{
        "Name": "Industry",
        "Value": "TMT"
      },
      {
        "Name": "Analyst",
        "Value": "Jen Cardage"
      }
    ]
  },
  {
    "Id": 2,
    "Name": "Software",
    "Labels": [],    
  },
  {
    "Id": 3,
    "Name": "Internet",
    "Labels": [{
        "Name": "Industry",
        "Value": "Tech"
      },
      {
        "Name": "Analyst",
        "Value": "Mike Smith"
      }
    ]
  }
]

This gets me objects with non-empty Labels, in this case, Ids 1 and 3.

const containsLabels = obj.filter(({Labels}) => Labels.length > 0);

However, I can't seem to figure out how to chain another map and/or filter onto containsLabels to map over and check against the Names and Value contained therein.

How can I get the object with Id: 3 out of containsLabels? My running code is here.

标签: javascript

解决方案


Labels is an array (as is obj), so running find() nested should do the trick:

const containsLabels = obj.filter(({ Labels }) => 
  Labels.find(({ Name, Value }) => Name === 'Industry' && Value === 'Tech')
);

I forked your fiddle with the working version.

It is unnecessary to filter for objects where Label.length > 0, because find() will return null when running on an empty array.

If Labels is not always present, the above code would throw an error. Instead, you can use the optional chaining operator (?.), or the traditional &&:

const containsLabels = obj.filter(({ Labels }) => 
  Labels?.find(({ Name, Value }) => Name === 'Industry' && Value === 'Tech')
);

// Or...
const containsLabels = obj.filter(({ Labels }) => 
  Labels && Labels.find(({ Name, Value }) => Name === 'Industry' && Value === 'Tech')
);

推荐阅读