Как найти объекты в массиве, где внутренний массив может включать другие объекты, используя lodash - PullRequest
1 голос
/ 29 февраля 2020

У меня есть следующие массивы:

const tasks = [
  {id: 0, name: 'a', tags: [{id: 0, name: 'q'}, {id: 1, name: 'w'}]},
  {id: 1, name: 'b', tags: [{id: 2, name: 'e'}, {id: 4, name: 't'}, {id: 11, name: 's'}]},
  {id: 2, name: 'c', tags: []},
  {id: 3, name: 'd', tags: [{id: 0, name: 'q'}, {id: 3, name: 'r'}, {id: 7, name: 'i'}]},
  {id: 6, name: 'g', tags: [{id: 7, name: 'i'}, {id: 4, name: 't'}]},
]

const tags = [
  {id: 0, name: 'q'},
  {id: 1, name: 'w'},
  {id: 2, name: 'e'},
  {id: 3, name: 'r'},
  {id: 4, name: 't'},
  {id: 7, name: 'i'},
  {id: 11, name: 's'}
]

let selectedTags = [0, 5]

selectedTags - это массив индексов tags Array. Теперь мне нужно найти все объекты в tasks Array, где свойство tags включает в себя любой из выбранных тегов. Таким образом, в этом случае вывод должен быть:

let result = [
  {id: 0, name: 'a', tags: [{id: 0, name: 'q'}, {id: 1, name: 'w'}]},
  {id: 3, name: 'd', tags: [{id: 0, name: 'q'}, {id: 3, name: 'r'}, {id: 7, name: 'i'}]},
  {id: 6, name: 'g', tags: [{id: 7, name: 'i'}, {id: 4, name: 't'}]}
]

Я пытался сделать что-то вроде этого:

let result= []
_.forEach(selectedTags, index => {
  const tagId = tags[index].id
  result = _.filter(tasks, task => _.some(task.tags, ['tag.id', tagId]))
})

, но я заканчиваю с пустым массивом. Я пытался использовать map, find и некоторые другие методы loda sh, но пока ничего не получалось.

Есть идеи, пожалуйста?

Ответы [ 2 ]

1 голос
/ 29 февраля 2020

Вы переназначаете отфильтрованный массив в каждой итерации, а также передаете в функцию .some массив, однако вместо этого следует передать объект ключ-значение.

Использовался следующий подход два вложенных вызова функции .some для проверки tags.id против selectedTag идентификаторов,

const tasks = [  {id: 0, name: 'a', tags: [{id: 0, name: 'q'}, {id: 1, name: 'w'}]},  {id: 1, name: 'b', tags: [{id: 2, name: 'e'}, {id: 4, name: 't'}, {id: 11, name: 's'}]},  {id: 2, name: 'c', tags: []},  {id: 3, name: 'd', tags: [{id: 0, name: 'q'}, {id: 3, name: 'r'}, {id: 7, name: 'i'}]},  {id: 6, name: 'g', tags: [{id: 7, name: 'i'}, {id: 4, name: 't'}]}],
      tags = [  {id: 0, name: 'q'},  {id: 1, name: 'w'},  {id: 2, name: 'e'},  {id: 3, name: 'r'},{id: 4, name: 't'},  {id: 7, name: 'i'},  {id: 11, name: 's'}],
      selectedTags = [0, 5],
      result = _.filter(tasks, ({tags: itags}) => _.some(itags, ({id}) => _.some(selectedTags, i => tags[i].id === id)));

console.log(result);
.as-console-wrapper {min-height: 100%;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.core.min.js"></script>
0 голосов
/ 29 февраля 2020

Вам нужно использовать filter() с вложенным some()

const tasks = [
  {id: 0, name: 'a', tags: [{id: 0, name: 'q'}, {id: 1, name: 'w'}]},
  {id: 1, name: 'b', tags: [{id: 2, name: 'e'}, {id: 4, name: 't'}, {id: 11, name: 's'}]},
  {id: 2, name: 'c', tags: []},
  {id: 3, name: 'd', tags: [{id: 0, name: 'q'}, {id: 3, name: 'r'}, {id: 7, name: 'i'}]},
  {id: 6, name: 'g', tags: [{id: 7, name: 'i'}, {id: 4, name: 't'}]},
]

const tags = [
  {id: 0, name: 'q'},
  {id: 1, name: 'w'},
  {id: 2, name: 'e'},
  {id: 3, name: 'r'},
  {id: 4, name: 't'},
  {id: 7, name: 'i'},
  {id: 11, name: 's'}
]

let selectedTags = [0, 5]
const res = tasks.filter(({tags}) => 
               tags.some(tag => 
                  selectedTags.some(index => tags[index].name === tag.name)
               )
            );
console.log(res)
...