Как отфильтровать вложенный массив в javascript по значениям из массива, чтобы он работал и с отдельными значениями?

#javascript #arrays

#javascript #массивы

Вопрос:

Я придумал пример из другой темы, который может отфильтровывать вложенный массив из другого массива, в котором хранятся значения фильтра.

Интересно, что когда в массиве есть один элемент, он работает плохо.

 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 = [3];
const r = data.filter(d => d.courses.every(c => courses.includes(c.id)));
console.log(r);
  

в случае моего примера мы должны видеть два 3, но вместо этого он дает нам первый.Как я могу отфильтровать этот вложенный массив с несколькими значениями или с одним?

Ответ №1:

Вы просите, чтобы ВСЕ / КАЖДЫЙ объект имел здесь id == 3, но вы хотите, чтобы ЛЮБОЙ / НЕКОТОРЫЕ объекты имели id == 3, как здесь:

 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 = [3];
const r = data
  .filter(d => d.courses.some(c => courses.includes(c.id)))
  .map(d => ({ ...d, courses: d.courses.filter(c => courses.includes(c.id))
  }));
console.log(r);  

Комментарии:

1. Этот приносит мне идентификатор 1. Я хочу видеть только идентификаторы, хранящиеся в массиве courses

2. Затем вам нужно снова изменить результирующий массив с помощью map, чтобы отфильтровать курсы, которых нет в утвержденном списке. Я обновил свое решение. Работает ли это для вас?

3. Да, работает отлично. Нет ли какого-либо способа добиться этого проще?

4. Пожалуйста, определите «проще». Если вы имеете в виду «без функций фильтра или сопоставления», то вам нужно использовать циклы for .

5. проще означает с меньшим количеством итераций

Ответ №2:

Если вы хотите найти все элементы в data , которые содержат все идентификаторы, найденные в const courses , то вам нужно инвертировать фильтрацию.

 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 = [3];
const r = data.filter(d => courses.every(courseId => d.courses.find(({
  id
}) => courseId === id)));
console.log(r);