简体   繁体   English

如何过滤具有特定属性的嵌套对象的对象数组?

[英]How to filter array of objects with nested objects with specific properties?

I am trying to filter a Javascript array of objects with nested objects with specific properties.我正在尝试过滤具有特定属性的嵌套对象的 Javascript 对象数组。 I can filter the name, slug, website, launch year without any issues.我可以毫无问题地过滤名称、slug、网站、发布年份。 But, I can not filter the category name (category.name) which is an object within the object.但是,我无法过滤作为对象内的对象的类别名称(category.name)。 Why is filtering the category name not working?为什么过滤类别名称不起作用?

            var search = "qui"; // does not work (category.name)
            // var search = "Sauer"; // works (name)

            var data = [{ "name": "Sauer-Metz", "slug": "ab-laborum", 
              "website": "https://test.com", "launch_year": 2017,  "category_id": 6,
              "category": { "id": 6, "name": "qui", "slug": "qui" } } ];

            var results = data.filter(company => [
                'name', 'launch_year', 'website', 'category.name'
            ].some(key => String(company[key]).toLowerCase().includes(search.toLowerCase())));

            console.log(results);

One way you can go about it is to have a value extractor like the one getKey below您可以采取的一种方法是拥有一个像下面的getKey这样的value提取器

const getKey = (value, key) => {
    return key.split('.').reduce((acc, curr) => value[curr], '');
 }
 
 

 var results = data.filter(company => [
            'name', 'launch_year', 'website', 'category.name'
        ].some(key => String(getKey(company, key)).toLowerCase().includes(search.toLowerCase())));

I believe you have to do a separate condition for this specific nested property, although there might be a cleaner way I don't see right now:我相信你必须为这个特定的嵌套属性做一个单独的条件,尽管可能有一种我现在看不到的更干净的方法:

var results = data.filter(
  (company) =>
    ["name", "launch_year", "website"].some((key) =>
      String(company[key]).toLowerCase().includes(search.toLowerCase())
    ) ||
    String(company["category"]["name"])
      .toLowerCase()
      .includes(search.toLowerCase())
);

Dot notation doesn't work like that.点符号不能这样工作。

 const testCase1 = 'qui'; const testCase2 = 'Sauer'; const data = [ { name: 'Sauer-Metz', slug: 'ab-laborum', website: 'https://test.com', launch_year: 2017, category_id: 6, category: { id: 6, name: 'qui', slug: 'qui' }, }, ]; const searchResults = (data, search) => { return data.filter((item) => { return ( item?.category?.name.toLowerCase().includes(search.toLowerCase()) || ['name', 'launch_year', 'website'].some((key) => `${item[key]}`.toLowerCase().includes(search.toLowerCase())) ); }); }; console.log('**CASE 1**') console.log(searchResults(data, testCase1)); console.log('**CASE 2**') console.log(searchResults(data, testCase2));

To use your approach you can convert 'category.name' to ['category','name'] and then use String(company[key[0]][key[1]])... whenever key is an array.要使用您的方法,您可以将'category.name'转换为['category','name'] ,然后在key是数组时使用String(company[key[0]][key[1]])...

 const search = "qui"; // does not work (category.name) //const search = "Sauer"; // works (name) const data = [{ "name": "Sauer-Metz", "slug": "ab-laborum", "website": "https://test.com", "launch_year": 2017, "category_id": 6, "category": { "id": 6, "name": "qui", "slug": "qui" } } ]; const results = data.filter( company => [ 'name', 'launch_year', 'website', ['category','name'] ].some( key => Array.isArray(key) ? String(company[key[0]][key[1]]).toLowerCase().includes(search.toLowerCase()) : String(company[key]).toLowerCase().includes(search.toLowerCase()) ) ); console.log(results);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM