简体   繁体   English

JS过滤数组在对象数组的对象属性中

[英]JS filtering array in object property of array of objects

I have js object like this 我有像这样的js对象

var continents = [
0: {
       short: 'na',
       countries: [
           {
               name: 'canada'
           },
           {
               name: 'usa'
           },
           //...
       ]

   },
   1: {
       short: 'sa',
       countries: [
           {
               name: 'chile'
           },
           {
               name: 'colombia'
           }
       ]

     },
//...
]

I want to filter this object for matches with country name (contents.countries.name) with some string (example 'col') Example filter function 我想过滤此对象以获取具有国家名称(contents.countries.name)的匹配项和一些字符串(示例'col')示例过滤器函数

filter(item => {
    return item.name.toLowerCase().indexOf('col'.toLowerCase()) >= 0;
});

Expecting result: 期待结果:

  1: {
       short: 'sa',
       countries: [
           {
               name: 'colombia'
           }
       ]
     }

You need to not only filter on the continents, but the countries within them. 您不仅需要过滤大陆,还要过滤其中的国家/地区。

This is a two-part filter, as seen below. 这是一个由两部分组成的过滤器,如下所示。

 var continents = [{ short: 'na', countries: [ { name: 'canada' }, { name: 'usa' } ] }, { short: 'sa', countries: [ { name: 'chile' }, { name: 'colombia' } ] }]; function filterByKeyValue(arr, keys, val) { return arr.filter(item => { return item[keys[0]].some(subitem => subitem[keys[1]].indexOf(val) > -1); }).map(item => { item[keys[0]] = item[keys[0]].filter(subitem => subitem[keys[1]].indexOf(val) > -1); return item; }); } var filtered = filterByKeyValue(continents, [ 'countries', 'name' ], 'col'); console.log(filtered); 
 .as-console-wrapper { top: 0; max-height: 100% !important; } 
 <!-- Original filter that method is based on. var filtered = continents.filter(continent => { return continent.countries.some(country => country.name.indexOf('col') > -1); }).map(continent => { continent.countries = continent.countries.filter(country => country.name.indexOf('col') > -1); return continent; }); --> 

item in this case has two properties, countries and short. 在这种情况下,项目有两个属性,国家和短。 You are trying to run .name on item, which doesn't exist. 您正尝试在项目上运行.name,该项目不存在。 You need to run .name on either item.countries[0].name or item.countries[1].name. 您需要在item.countries [0] .name或item.countries [1] .name上运行.name。

    var continents = [
        {
            short: 'na',
            countries: [
                {
                    name: 'canada'
                },
                {
                    name: 'usa'
                }
            ]

        },
        {
            short: 'sa',
            countries: [
                {
                    name: 'chile'
                },
                {
                    name: 'colombia'
                }
            ]

        }
    ];

    var results = continents.filter(item => {
        return item.countries[0].name.toLowerCase().indexOf('col'.toLowerCase()) >= 0 || 
item.countries[1].name.toLowerCase().indexOf('col'.toLowerCase()) >= 0
    });

    console.log(results);

Working example: https://jsfiddle.net/gugui3z24/fnw5kf0x/ 工作示例: https//jsfiddle.net/gugui3z24/fnw5kf0x/

You can use the filter function to return just the items that match a condition. 您可以使用filter函数仅返回与条件匹配的项目。 Like so: 像这样:

const matches = [];
continents.forEach((continent) => {

  const countries = continent.countries.filter((country) => {
    return country.name.includes('col');
  });

  matches.push(...countries);
});

Note: I have used the spread operator ... to flattern the array (avoiding an array of arrays). 注意:我使用了spread运算符...来平坦化数组(避免使用数组数组)。

For a loop you could use: 对于循环,您可以使用:

var continents = [
    {
        short: 'na',
        countries: [
            {
                name: 'canada'
            },
            {
                name: 'usa'
            }
        ]
    },
    {
        short: 'sa',
        countries: [
            {
                name: 'chile'
            },
            {
                name: 'colombia'
            }
        ]
    }
];

var results = continents.filter(item => {
    for (let x = 0; x < item.countries.length; x++) {
        if (item.countries[x].name.toLowerCase().indexOf('usa') > -1) {
            return item;
            break;
        }
    }
});

console.log(results);

Working example: https://jsfiddle.net/gugui3z24/fnw5kf0x/2/ 工作示例: https//jsfiddle.net/gugui3z24/fnw5kf0x/2/

You could try to filter the countries and if one found, push the outer continent as well to the result set. 您可以尝试过滤这些国家/地区,如果找到了,也可以将外部大陆推送到结果集。

 function getItems(name) { var result = []; continents.forEach(function (continent) { var countries = continent.countries.filter(function (country) { return country.name.startsWith(name); }); if (countries.length) { result.push({ short: continent.short, countries: countries }); } }); return result; } var continents = [{ short: 'na', countries: [{ name: 'canada' }, { name: 'usa' }] }, { short: 'sa', countries: [{ name: 'chile' }, { name: 'colombia' }] }]; console.log(getItems('col')); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

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

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