Добавить val.hierarchy в массив объектов

Вот массив

const arr = [
  {name: "Earth", id: 1, parent_id: -1},
  {name: "Europe", id: 2, parent_id: 1},
  {name: America": id: 3, parent_id: 1},
  {name: "Asia", id: 4, parent_id: 1}
];

Мне нужно добавить ключ иерархии к каждому элементу массива, который будет содержать массив.

const arr = [
  {name: "Earth", id: 1, parent_id: -1, hierarchy: ["Earth"]},
  {name: "Europe", id: 2, parent_id: 1, hierarchy: ["Earth", "Europe"]},
  {name: America": id: 3, parent_id: 1, hierarchy: ["Earth", "America"]},
  {name: "Asia", id: 4, parent_id: 1, hierarchy: ["Earth", "Asia"]}
];

Я пытаюсь сделать это с помощью lodash find

const parent = _.find(arr, { id: val.parent_id });

    if (parent === undefined) {
      val.hierarchy = [val.id];
    } else {
      val.hierarchy = [...parent.hierarchy, val.id];
    }

Но я всегда получаю родительский === неопределенный

arr.map(e => { const parent = arr.find(x => x.id === e.parent_id); const hierarchy = []; if (parent) hierarchy.push(parent.name); hierarchy.push(e.name); return {...e, hierarchy}; })
cmgchess 01.05.2024 11:01
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
1
51
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Для этого вам не нужен lodash. Просто соберите предметы в объект и используйте его, чтобы получить путь.

Конечно, вы можете использовать альтернативу Array#forEach lodash или просто циклы for..of.

const arr = [
  {name: "Earth", id: 1, parent_id: -1},
  {name: "Europe", id: 2, parent_id: 1},
  {name: "America", id: 3, parent_id: 1},
  {name: "Asia", id: 4, parent_id: 1},
  {name: "New York", id: 5, parent_id: 3},
];

const items = {};
arr.forEach(item => items[item.id] = item);
const traverse = item => item ? traverse(items[item.parent_id]).concat(item.name) : [];
arr.forEach(item => item.hierarchy = traverse(item));


arr.forEach(i=>console.info(JSON.stringify(i)));
.as-console-wrapper{max-height:100%!important}

Вы можете собрать все узлы и их родителей и построить новый массив с иерархиями.

const
    getParents = id => id in references.ids
        ? [...getParents(references.parents[id]), references.ids[id].name]
        : [],
    data = [{ name: "Earth", id: 1, parent_id: -1 }, { name: "Europe", id: 2, parent_id: 1 }, { name: "America", id: 3, parent_id: 1 }, { name: "Asia", id: 4, parent_id: 1 }],
    references = data.reduce((r, o) => {
        r.ids[o.id] = o;
        r.parents[o.id] = o.parent_id;
        return r;
    }, { ids: {}, parents: {} }),
    result = data.map(o => ({ ...o, hierarchy: getParents(o.id) }));

console.info(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Предполагаю, что для всех объектов lhs.id < rhs.id => lhs.parent_id < rhs.id.

Мы сделаем это двумя способами:

  1. Связать и ID с соответствующим объектом
  2. Отсортируйте массив по id
  3. Постройте hierarchy недвижимость

const arr = [
  {name: "Earth", id: 1, parent_id: -1},
  {name: "Europe", id: 2, parent_id: 1},
  {name: "America", id: 3, parent_id: 1},
  {name: "Asia", id: 4, parent_id: 1},
];

// 1. Store a mapping from ID to object for easy access
const mapping = new Map(arr.map(obj => [obj.id, obj]));

// 2. (optional) sort by ID to ensure the precondition
arr.sort((lhs, rhs) => {
  if (lhs.id == rhs.id) {
    return 0;
  }

  return lhs.id < rhs.id ? -1 : 1;
});

// 3. Build the hierarchy
arr.forEach(obj => {
  if (obj.parent_id < 0) {
    obj.hierarchy = [obj.name];
    return;
  }

  if (!mapping.has(obj.parent_id)) {
    // This is a possibility, do what you wish here
    obj.hierarchy = ["<incomplete>", obj.name];
    return;
  }

  const parent = mapping.get(obj.parent_id);
  const parentHierarchy = parent.hierarchy;
  obj.hierarchy = [...parentHierarchy, obj.name];
});

console.info(arr);

Другие вопросы по теме