Поиск наилучшего способа обработки (извлечения / изменения) вложенного объекта в JS / TS

#javascript #typescript

#javascript #typescript

Вопрос:

У меня есть объект ниже. Я хочу добавить дополнительное свойство, например «категория»: «У меня нет дочерних объектов» ко всем этим дочерним объектам (с именем «какое-то имя 111, какое-то имя 222 ….»), у которых нет дочерних объектов

 {
            "name":"Grand Parent",
            "children":[
                {
                "name":"Parent 1",
                "children":[
                    {
                        "name":"some name 111",
                        "qty":1                         
                    },
                    {
                        "name":"some name 222",
                        "qty":1
                    }
                ]
                },
                {
                    "name":"Parent 2",
                    "children":[
                        {
                            "name":"some name 333",
                            "qty":1
                        },
                        {
                            "name":"some name 444",
                            "qty":1
                        }
                    ]
                },
                {
                    "name":"Parent 3",
                    "children":[
                        {
                            "name":"some name 555",
                            "qty":1
                        }
                    ]
                },
                {
                    "name":"Parent 4",
                    "children":[
                        {
                            "name":"some name 666",
                            "qty":1
                        }
                    ]
                }
            ]
        }
 

Ответ №1:

Вы можете сделать это с помощью forEach , с объектом, который проверяется на наличие дочерних элементов. Если он отсутствует, то child['category'] = "I don't have any child" может быть добавлен к объекту. Это настраивается только для двух уровней глубины (как указано в вопросе).

 data.children.forEach(parent => {
  if (!parent.children)
    parent['category'] = "I don't have any child"
  else
    parent.children.forEach(child => {
      if (!child.children)
        child['category'] = "I don't have any child"
    })
})

 

Фрагмент кода:

 const data = { "name": "Grand Parent", "children": [{ "name": "Parent 1", "children": [{ "name": "some name 111", "qty": 1 }, { "name": "some name 222", "qty": 1 }] }, { "name": "Parent 2", "children": [{ "name": "some name 333", "qty": 1 }, { "name": "some name 444", "qty": 1 }] }, { "name": "Parent 3", "children": [{ "name": "some name 555", "qty": 1 }] }, { "name": "Parent 4", "children": [{ "name": "some name 666", "qty": 1 }] }] }

data.children.forEach(parent => {
  if (!parent.children)
    parent['category'] = "I don't have any child"
  else
    parent.children.forEach(child => {
      if (!child.children)
        child['category'] = "I don't have any child"
    })
})

console.log(data) 

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

1. Это может работать до тех пор, пока гарантируется, что глубина данных составляет ровно два уровня, но в противном случае может потребоваться, чтобы рекурсивная функция погружалась настолько глубоко, насколько это необходимо. Кроме того, я бы рекомендовал использовать forEach вместо map , поскольку вы ничего не возвращаете из обратных вызовов.

Ответ №2:

Я бы реализовал рекурсивную функцию, которая добавляет свойство к объекту, если у него нет children prop, и, в противном случае, вызывает ту же самую рекурсивную функцию для каждого элемента в его children массиве.

 const obj = { "name":"Grand Parent", "children":[ { "name":"Parent 1", "children":[ { "name":"some name 111", "qty":1
}, { "name":"some name 222", "qty":1 } ] }, { "name":"Parent 2", "children":[ { "name":"some name 333", "qty":1 }, { "name":"some name 444", "qty":1 } ] }, { "name":"Parent 3", "children":[ { "name":"some name 555", "qty":1 } ] }, { "name":"Parent 4", "children":[ { "name":"some name 666", "qty":1 } ] } ] };

function checkChildren(obj) {
  if (!obj.hasOwnProperty("children")) {
    obj.category = "I have no children";
  } else {
    obj.children.forEach(child => {
      checkChildren(child);
    })
  }
}

checkChildren(obj);

console.log(obj);