简体   繁体   English

按值数组过滤对象数组中的嵌套数组

[英]Filter nested array in object array by array of values

Considering below object array:考虑下面的对象数组:

[
    {
        "guid": "j5Dc9Z",            
        "courses": [
            {
                "id": 1,
                "name": "foo",                    
            }
        ]
    },
    {
        "guid": "a5gdfS",
        "courses": [
            {
                "id": 2,
                "name": "bar",                    
            },
            {
                "id": 3,
                "name": "foo",                    
            },    
        ]
     },
     {
        "guid": "jHab6i",
        "courses": [
            {
                "id": 4,
                "name": "foobar",                    
            }   
        ]
     },  
     {...}    
]

I am trying to filter an object array, comparing IDs in the nested courses array with in the below array:我正在尝试过滤对象数组,将嵌套courses数组中的 ID 与以下数组中的 ID 进行比较:

filter.courses = [1,3]

The following line works for the nth value in the array: (via https://stackoverflow.com/a/41347441/9766768 )以下行适用于数组中的第 n 个值:(通过https://stackoverflow.com/a/41347441/9766768

let fil = filter(this.results, { courses: [{ id: this.filter.courses[n] }]});

However, I'm hoping to achieve this (pseudo code below):但是,我希望实现这一点(下面的伪代码):

let fil = filter(this.results, { courses: [{ id: this.filter.courses }]});

Expected output would be an array of objects containing any of the course IDs elements, in this case:预期的输出将是一个包含任何课程 ID 元素的对象数组,在本例中:

[
    {
        "guid": "j5Dc9Z",            
        "courses": [
            {
                "id": 1,
                "name": "foo",                    
            }
        ]
    },
    {
        "guid": "a5gdfS",
        "courses": [
            {
                "id": 2,
                "name": "bar",                    
            },
            {
                "id": 3,
                "name": "foo",                    
            },    
        ]
     }   
]

What would be considered the best solution in this case?在这种情况下,什么被认为是最好的解决方案? Avoiding loops would be a bonus.避免循环将是一个奖励。

If you're trying to filter the elements whose course IDs contain in the filter.courses , you may use Array#every and Array#includes to do that:如果您尝试过滤其课程 ID 包含在filter.courses中的元素,您可以使用Array#everyArray#includes来执行此操作:

 const data = [{"guid":"j5Dc9Z","courses":[{"id":3,"name":"foo"}]},{"guid":"a5gdfS","courses":[{"id":1,"name":"bar"},{"id":3,"name":"foo"}]},{"guid":"jHab6i","courses":[{"id":7,"name":"foobar"}]}]; const courses = [1, 6, 3]; const r = data.filter(d => d.courses.every(c => courses.includes(c.id))); console.log(r);

try this,尝试这个,

 results = [ { "guid": "j5Dc9Z", "courses": [ { "id": 3, "name": "foo", } ] }, { "guid": "a5gdfS", "courses": [ { "id": 1, "name": "bar", }, { "id": 3, "name": "foo", }, ] } ] var filter = [1] console.log(results.map(result=>{ result.courses = result.courses.filter(course=>(filter.includes(course.id))) return result }))

Explore my recursive solution there: Playground Link在那里探索我的递归解决方案: Playground Link

With this solution can nested array of objects being filtered from top level to botton level, layer by layer.使用此解决方案,可以逐层从顶层过滤到底层的嵌套对象数组。

From what I understand the resulting array should contain all objects, that contain at least one course with an id that is contained in the array we use to filter.据我了解,结果数组应包含所有对象,这些对象至少包含一门课程,其 id 包含在我们用于过滤的数组中。

So if an object exists with 2 courses - and one of them has an id we are looking for this object should then be part of the array that gets returned (see object with property "guid" : "a5gdfS" in the questions example)因此,如果一个对象存在 2 个课程 - 其中一个有一个 id,我们正在寻找这个对象应该是返回的数组的一部分(请参阅问题示例中具有属性“guid”:“a5gdfS”的对象)

With one little tweak the code provided in the answer by 31piy (marked as best by question owner) will do exactly what we desire.只需稍加调整,31piy 在答案中提供的代码(由问题所有者标记为最佳)将完全符合我们的要求。 To do so we just change the array method every() to the array method some().为此,我们只需将数组方法every() 更改为数组方法some()。

const r = data.filter(d => d.courses. every (c => courses.includes(c.id))); const r = data.filter(d => d.courses.every (c => course.includes(c.id)));

const r = data.filter(d => d.courses. some (c => courses.includes(c.id))); const r = data.filter(d => d.courses.some (c => courses.includes(c.id)));

With the method every() the resulting array will only contain the objects, where each and every course has an id we are looking for.使用 every() 方法,结果数组将只包含对象,其中每门课程都有我们正在寻找的 id。 ("guid": "a5gdfS" is not in the resulting array) (“guid”:“a5gdfS”不在结果数组中)

With the method some() the resulting array will contain the objects, where at least one course has an id we are looking for ("guid": "a5gdfS" is in the resulting array)使用 some() 方法,结果数组将包含对象,其中至少一门课程具有我们正在寻找的 id(“guid”:“a5gdfS”在结果数组中)

 /* arrays are the same as provided in the question so that we can check against expected/desired output in the question */ const data = [{ "guid": "j5Dc9Z", "courses": [{ "id": 1, "name": "foo", }] }, { "guid": "a5gdfS", "courses": [{ "id": 2, "name": "bar", }, { "id": 3, "name": "foo", }, ] }, { "guid": "jHab6i", "courses": [{ "id": 4, "name": "foobar", }] } ]; const courses = [1, 3]; //array contains all objects with at least 1 course that has an id we are looking for const r = data.filter(d => d.courses.some(c => courses.includes(c.id))); console.log("code with some " + JSON.stringify(r)); //array contains only objects, whose classes all have an id we are looking for const o = data.filter(d => d.courses.every(c => courses.includes(c.id))); console.log("code with every " + JSON.stringify(o));

depending on what we are trying to do either every() or some() might be correct - depends on what we are trying to achieve取决于我们试图做什么,every() 或 some() 可能是正确的 - 取决于我们想要实现的目标

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

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