#javascript #arrays #recursion #filter #dataset
#javascript #массивы #рекурсия #Фильтр #набор данных
Вопрос:
Я пытаюсь написать функцию для поиска потомков человека. Имеющиеся у меня данные настроены в массив и отформатированы следующим образом:
{
"id": 159819275,
"firstName": "Jasmine",
"lastName": "Bob",
"gender": "female",
"dob": "12/18/1969",
"height": 58,
"weight": 156,
"eyeColor": "blue",
"occupation": "assistant",
"parents": [409574486, 260451248],
"currentSpouse": 951747547
},
Функция, которую я написал, принимает идентификатор человека, потомков которого я ищу, массив людей и создает новый массив, содержащий потомков.
function findDescendants (id, people, descendantsArray = []){
descendantsArray = people.filter(function(el){
return el.parents[0] === id || el.parents[1 === id] //id works if it's a variable, but if it's a array it won't work. otherwise function is good
})
displayPeople(descendantsArray) //calls a method that alerts the descendant's names into a string
id = []; //resets the id and turns it into an array
for(let i = 0; i<descendantsArray.length; i ){
id[i] = descendantsArray[i].id
} //puts the id's of the listed descendants into the array id
if (descendantsArray.length === 0){
return descendantsArray;
}
else {
findDescendants(id, people, descendantsArray)
} //sends in the array id, the data set people, and the descendantsArray (which contains the children of the person in question.
}
Моя проблема в том, что когда я вызываю массив во второй раз, фильтр не сравнивает el.parents со всеми элементами в id, и я не уверен, что делать дальше.
descendantsArray = people.filter(function(el){
return el.parents[0] === id || el.parents[1 === id] //id works if it's a variable, but if it's a array it won't work. otherwise function is good
})
я бы хотел, чтобы это утверждение отфильтровывало все элементы в людях, чьи «родители: » содержат любой из элементов в массиве id. Буду признателен за любую помощь.
Комментарии:
1.
el.parents[1 === id]
Вы, вероятно, имели в виду это?el.parents[1] === id
Ответ №1:
Вы можете написать что-то вроде этого:
const getDescendents = (people, id) =>
people .filter (({parents = []}) => parents .includes (id))
.flatMap (person => [person, ... getDescendents (people, person.id)])
Если бы у нас было такое дерево:
Alice Bob
|
--------------- --------------
| |
Charlie Denise Edward Francine
| |
------ ------- |
| | |
Geroge Helen Irwin Jean Kayleigh
|
|
|
Leroy
и мы вызвали getDescendents(people, 1)
(где у Алисы есть идентификатор 1
), мы получили бы обратно объекты, представляющие этих людей : [Denise, Helen, Irwin, Leroy, Edward, Kayleigh]
. Это включает в себя обход данных в глубину, предварительный порядок. Если бы мы хотели выполнить сортировку (по идентификатору или чему-то еще), мы могли бы сделать это после вызова или — с небольшим снижением производительности — в качестве последнего шага функции:
const getDescendents = (people, id) =>
people .filter (({parents = []}) => parents .includes (id))
.flatMap (person => [person, ... getDescendents (people, person.id)])
.sort (({id: a}, {id: b}) => a - b)
const people = [{name: 'Alice', id: 1, parents: []}, {name: 'Bob', id: 2, parents: []}, {name: 'Charlie', id: 3, parents: []}, {name: 'Denise', id: 4, parents: [1, 2]}, {name: 'Edward', id: 5, parents: [1, 2]}, {name: 'Francine', id: 6, parents: []}, {name: 'George', id: 7, parents: []}, {name: 'Helen', id: 8, parents: [3, 4]}, {name: 'Irwin', id: 9, parents: [3, 4]}, {name: 'Jean', id: 10, parents: []}, {name: 'Kayleigh', id: 11, parents: [5, 6]}, {name: 'Leroy', id: 12, parents: [9, 10]}]
people .forEach (
({name, id}) => console .log (
`${name} ==> [${getDescendents(people, id).map(({name}) => name).join(', ')}]`
)
)
console .log ('Denise's descendents: ', getDescendents (people, 4))
.as-console-wrapper {max-height: 100% !important; top: 0}