Определение самого дальнего родственника по ID

Есть JSON с со списком людей, в котором у каждого человека есть свой ID и его родителей. Люди могут не являться друг другу родственниками. Сама задача в том, чтобы по введенному ID находился самый дальний родственник.

Вот один из элементов JSON:

{
    "ID": "1",
    "firstName": "Андрей",
    "paternalName": "Михайлович",
    "lastName": "Бойко",
    "mother": "15",
    "father": "27",
    "": ""
}

"Последний" родственник будет иметь "" в полях mother и father. Пробовал через for, вложенный в while, но так он проходит только по одной ветке. В инете ничего внятного не смог найти.


Ответы (2 шт):

Автор решения: Pavel

если я вас правильно понял, и объект содержит только список родственников (без посторонних людей)

var grandmother, Granddad;
for(key in obj){
 if(obj[key].mother == '') grandmother= obj[key].ID
 if(obj[key].father == '') Granddad = obj[key].ID
 if(grandmother != undefined && Granddad!= undefined) break;
}
alert('id Бабушки: '+grandmother+'. id Дедушки'+Granddad);
→ Ссылка
Автор решения: entithat

Не заметил сразу, что это бинарное дерево :) Тогда просто ищем максимальную глубину этого дерева.

function getOldestRelative(id) {
  // Вспомагательная функция
  const findIndex = (v, a) => people.findIndex(e => e.ID == v);

  function maxDepth(node, num) {
    // Ищем индекс мамы и папы в массиве
    const mother = findIndex(node.mother);
    const father = findIndex(node.father);

    // Если это последний человек в роду, выводим его id
    if (mother === -1 && father === -1)
      return { num: num, user: node };

    // Если есть мама и папа, ищем того, кто дальше
    if (mother !== -1 && father !== -1){
      const f = maxDepth(people[father], num + 1);
      const m = maxDepth(people[mother], num + 1);
      return f.num > m.num ? f : m;
    }
    
    // Иначе проходимся по кому-то одному
    return maxDepth(people[father !== -1 ? father : mother], num + 1).num;
  }

  // Начинаем с нужного нам человека (ищем его по id)
  const idx = findIndex(id);
  if (idx === -1) 
    throw new Error('User does not exists');
  
  return maxDepth(people[idx], 0);
}

const people = [
    {
        "ID": "1",
        "firstName": "Алексей",
        "paternalName": "Семенович",
        "lastName": "Василенко",
        "mother": "",
        "father": "",
        "gender": "М",
        "spouse": "4",
        "birthDate": "12.08.1965",
        "deathDate": "",
        "": ""
    },
    {
        "ID": "11",
        "firstName": "Антонина",
        "paternalName": "Игнатьевна",
        "lastName": "Виноградова",
        "mother": "",
        "father": "",
        "gender": "Ж",
        "spouse": "1",
        "birthDate": "21.09.1977",
        "deathDate": "",
        "": ""
    },
    {
        "ID": "2",
        "firstName": "Геннадий",
        "paternalName": "Петрович",
        "lastName": "Белов",
        "mother": "",
        "father": "",
        "gender": "М",
        "spouse": "12",
        "birthDate": "19.01.1980",
        "deathDate": "",
        "": ""
    },
    {
        "ID": "34",
        "firstName": "Василиса",
        "paternalName": "Антоновна",
        "lastName": "Ковалёва",
        "mother": "",
        "father": "",
        "gender": "Ж",
        "spouse": "",
        "birthDate": "11.12.1975",
        "deathDate": "",
        "": ""
    },
    {
        "ID": "23",
        "firstName": "Светлана",
        "paternalName": "Алексеевна",
        "lastName": "Василенко",
        "mother": "11",
        "father": "1",
        "gender": "Ж",
        "spouse": "",
        "birthDate": "24.11.1973",
        "deathDate": "",
        "": ""
    },
    {
        "ID": "32",
        "firstName": "Андрей",
        "paternalName": "Алексеевич",
        "lastName": "Василенко",
        "mother": "11",
        "father": "1",
        "gender": "Ж",
        "spouse": "",
        "birthDate": "12.11.1980",
        "deathDate": "",
        "": ""
    },
    {
        "ID": "12",
        "firstName": "Раиса",
        "paternalName": "Алексеевна",
        "lastName": "Белова",
        "mother": "11",
        "father": "1",
        "gender": "М",
        "spouse": "2",
        "birthDate": "18.08.2001",
        "deathDate": "",
        "": ""
    },
    {
        "ID": "8",
        "firstName": "Андрей",
        "paternalName": "Викторович",
        "lastName": "Владыкин",
        "mother": "21",
        "father": "36",
        "gender": "М",
        "spouse": "14",
        "birthDate": "22.04.1979",
        "deathDate": "",
        "": ""
    },
    {
        "ID": "14",
        "firstName": "Алиса",
        "paternalName": "Геннадьевна",
        "lastName": "Владыкина",
        "mother": "",
        "father": "2",
        "gender": "Ж",
        "spouse": "8",
        "birthDate": "12.08.1973",
        "deathDate": "",
        "": ""
    },
    {
        "ID": "36",
        "firstName": "Петр",
        "paternalName": "Васильевич",
        "lastName": "Владыкин",
        "mother": "77",
        "father": "55",
        "gender": "М",
        "spouse": "21",
        "birthDate": "09.07.1981",
        "deathDate": "",
        "": ""
    },
    {
        "ID": "21",
        "firstName": "Тамара",
        "paternalName": "Петровна",
        "lastName": "Владыкина",
        "mother": "67",
        "father": "35",
        "gender": "Ж",
        "spouse": "36",
        "birthDate": "26.04.1980",
        "deathDate": "",
        "": ""
    },
    {
        "ID": "33",
        "firstName": "Алексей",
        "paternalName": "",
        "lastName": "Мишкин",
        "mother": "",
        "father": "",
        "gender": "M",
        "spouse": "",
        "birthDate": "21.05.1986",
        "deathDate": "",
        "": ""
    },
    {
        "ID": "35",
        "firstName": "Петр",
        "paternalName": "Ефставьевич",
        "lastName": "Вишневецкий",
        "mother": "",
        "father": "",
        "gender": "М",
        "spouse": "",
        "birthDate": "05.12.1999",
        "deathDate": "",
        "": ""
    },
    {
        "ID": "45",
        "firstName": "Альбина",
        "paternalName": "Васильевна",
        "lastName": "Мельник",
        "mother": "67",
        "father": "55",
        "gender": "Ж",
        "spouse": "",
        "birthDate": "19.01.1990",
        "deathDate": "",
        "": ""
    },
    {
        "ID": "67",
        "firstName": "Алла",
        "paternalName": "Витальевна",
        "lastName": "Мерзлова",
        "mother": "",
        "father": "",
        "gender": "Ж",
        "spouse": "",
        "birthDate": "04.02.2005",
        "deathDate": "",
        "": ""
    },
    {
        "ID": "55",
        "firstName": "Василий",
        "paternalName": "Анатольевич",
        "lastName": "Владыкин",
        "mother": "",
        "father": "",
        "gender": "М",
        "spouse": "",
        "birthDate": "23.04.1940",
        "deathDate": "12.03.1999",
        "": ""
    },
    {
        "ID": "77",
        "firstName": "Марина",
        "paternalName": "Семеновна",
        "lastName": "Литвиненко",
        "mother": "4",
        "father": "1",
        "gender": "Ж",
        "spouse": "",
        "birthDate": "18.07.1995",
        "deathDate": "",
        "": ""
    },
    {
        "ID": "3",
        "firstName": "Василий",
        "paternalName": "Семенович",
        "lastName": "Василенко",
        "mother": "4",
        "father": "1",
        "gender": "М",
        "spouse": "",
        "birthDate": "07.10.1993",
        "deathDate": "",
        "": ""
    },
    {
        "ID": "4",
        "firstName": "Лариса",
        "paternalName": "Илларионовна",
        "lastName": "Василенко",
        "mother": "",
        "father": "",
        "gender": "Ж",
        "spouse": "1",
        "birthDate": "12.11.1989",
        "deathDate": "",
        "": ""
    },
    {
        "ID": "5",
        "firstName": "Светлана",
        "paternalName": "Семеновна",
        "lastName": "Василенко",
        "mother": "4",
        "father": "1",
        "gender": "Ж",
        "spouse": "",
        "birthDate": "15.03.1982",
        "deathDate": "",
        "": ""
    },
    {
        "ID": "19",
        "firstName": "Спицин",
        "paternalName": "Николай",
        "lastName": "Дмитриевич",
        "mother": "",
        "father": "",
        "gender": "М",
        "spouse": "19",
        "birthDate": "01.09.1966",
        "deathDate": "",
        "": ""
    },
    {
        "ID": "22",
        "firstName": "Валентина",
        "paternalName": "Эдуардовна",
        "lastName": "Миллер",
        "mother": "",
        "father": "",
        "gender": "Ж",
        "spouse": "22",
        "birthDate": "15.2.1969",
        "deathDate": "",
        "": ""
    }
];

console.log(getOldestRelative(8).user);
console.log(getOldestRelative(32).user);

→ Ссылка