Слияние и вложение объектов JavaScript - PullRequest
1 голос
/ 11 июля 2019

У меня есть два объекта javascript, я хочу изменить структуру одного из них и объединить другой в первый

Я использовал петли, но это не лучший способ сделать это

Мой первый объект называется navbar

navbar:
   [ { Id: 7,
       ParentId: null,
       Name: 'Home',
       Slug: '/',
       Priority: 1,
       MenuDisplay: true,
       MenuSubDisplay: false,
       MobileDisplay: false,
       PageType: 'Custom Plus' },
     { Id: 15,
       ParentId: 14,
       Name: 'About Us',
       Slug: 'about-us',
       Priority: 1,
       MenuDisplay: true,
       MenuSubDisplay: false,
       MobileDisplay: false,
       PageType: 'Custom Plus' },
     { Id: 8,
       ParentId: null,
       Name: 'New Cars',
       Slug: 'new-cars',
       Priority: 2,
       MenuDisplay: true,
       MenuSubDisplay: false,
       MobileDisplay: false,
       PageType: 'Custom' },
     { Id: 14,
       ParentId: null,
       Name: 'More',
       Slug: 'more',
       Priority: 8,
       MenuDisplay: true,
       MenuSubDisplay: false,
       MobileDisplay: false,
       PageType: 'Placeholder' } ]

А мой второй называется newvehicles:

newvehicles:
   [ { Id: 5,
       VehicleType: 'Car',
       MakeId: 5,
       MakeName: 'Make',
       MakeSlug: 'make',
       ModelId: 13,
       ModelName: 'All-New Car',
       ModelSlug: 'all-new-car',
       Prefix: null,
       Suffix: null,
       Priority: 1,
       Redirect: null,
       Image:
        'http://xxxx.jpg',
       Assets: null,
       Markup: null },
     { Id: 6,
       VehicleType: 'Car',
       MakeId: 5,
       MakeName: 'Car',
       MakeSlug: 'Car',
       ModelId: 8,
       ModelName: 'Car',
       ModelSlug: 'Car',
       Prefix: null,
       Suffix: null,
       Priority: 2,
       Redirect: null,
       Image:
        'http://xxxx.jpg',
       Assets: null,
       Markup: null } ] 

Чего я хочу добиться, так это чтобы объект новых транспортных средств вставлялся в панель навигации как дочерний элемент «новых автомобилей», а также проходил через панель навигации и перемещал все объекты с ненулевым ParentId для перемещения в этот родительский объект как ребенок

В настоящее время я использую цикл for для внесения некоторых изменений:

    for (var i = 0; i < navigation.navbar.length; i++) {
      var obj = navigation.navbar[i];
      if (obj.Slug == 'new-cars') {
        obj.child = newvehicles;
      }
    }

Но я ищу вывод, похожий на этот:

navbar:
   [ { Id: 7,
       ParentId: null,
       Name: 'Home',
       Slug: '/',
       Priority: 1,
       MenuDisplay: true,
       MenuSubDisplay: false,
       MobileDisplay: false,
       PageType: 'Custom Plus' },
     { Id: 8,
       ParentId: null,
       Name: 'New Cars',
       Slug: 'new-cars',
       Priority: 2,
       MenuDisplay: true,
       MenuSubDisplay: false,
       MobileDisplay: false,
       PageType: 'Custom'.
child :  [ { Id: 5,
       VehicleType: 'Car',
       MakeId: 5,
       MakeName: 'Make',
       MakeSlug: 'make',
       ModelId: 13,
       ModelName: 'All-New Car',
       ModelSlug: 'all-new-car',
       Prefix: null,
       Suffix: null,
       Priority: 1,
       Redirect: null,
       Image:
        'http://xxxx.jpg',
       Assets: null,
       Markup: null },
     { Id: 6,
       VehicleType: 'Car',
       MakeId: 5,
       MakeName: 'Car',
       MakeSlug: 'Car',
       ModelId: 8,
       ModelName: 'Car',
       ModelSlug: 'Car',
       Prefix: null,
       Suffix: null,
       Priority: 2,
       Redirect: null,
       Image:
        'http://xxxx.jpg',
       Assets: null,
       Markup: null } ]        },
     { Id: 14,
       ParentId: null,
       Name: 'More',
       Slug: 'more',
       Priority: 8,
       MenuDisplay: true,
       MenuSubDisplay: false,
       MobileDisplay: false,
       PageType: 'Placeholder',
child:     { Id: 15,
       ParentId: 14,
       Name: 'About Us',
       Slug: 'about-us',
       Priority: 1,
       MenuDisplay: true,
       MenuSubDisplay: false,
       MobileDisplay: false,
       PageType: 'Custom Plus' }       } ]

Ответы [ 2 ]

2 голосов
/ 11 июля 2019

Представленная вами логика зацикливания, кажется, уже соответствует вашей цели относительно добавления логики машин.Тем не менее, в вашем запросе подразумевается, что будет только одна запись с фрагментом «new-cars».Если это так, тогда рассмотрите:

navbar.find(item => item.Slug == 'new-cars').child = newvehicles;

Что касается ненулевого parentId, вы можете:

  • перебирать цикл назад во внешнем массиве,
  • в пределахв цикле найдите все элементы массива, чей идентификатор совпадает с parentId текущего элемента,
  • склеивает текущий элемент (дочерний элемент)
  • , загружает его в свойство 'child' полученного родителя,

Вот код:

for (var i = navbar.length - 1; i >= 0; i--) {
  var obj = navbar[i];
  let parent = navbar.find(item => item.Id == obj.ParentId);
  if (parent) {
    parent.child = navbar.splice(i,1);    
  }
}

В обоих случаях префикс «навигация».на 'navbar' и / или 'newvehicles' по мере необходимости.

Редактировать: Чтобы справиться с приведенным ниже комментарием ОП, запрашивающим возможность ассоциировать нескольких детей с родителем.

Чтобы свойство child позволяло использовать несколько дочерних элементов, мы превратили его в массив.Поэтому мы сначала проверим, существует ли свойство child в родительском объекте.Если нет, мы создаем его и устанавливаем равным пустому массиву.Затем мы помещаем дочерний объект в цикле:

for (var i = navbar.length - 1; i >= 0; i--) {
  var obj = navbar[i];
  let parent = navbar.find(item => item.Id == obj.ParentId);
  if (parent) {
    if (!parent.child)
        parent.child = [];
    parent.child.push(navbar.splice(i,1)[0]);    
  }
}

Рассмотрите возможность изменения имени 'child' на 'children' для своих нужд.

Также учтите, что всеэто будет работать только для одного уровня.Если вам нужно многоуровневое вложение родителей в детей, то простого цикла не хватит.Вы можете создать другой вопрос в этом случае.

0 голосов
/ 11 июля 2019

Вот решение, основанное на Lodash-fp

Это вариант библиотеки Lodash, который допускает полнофункциональный стиль программирования и упрощает задачи такого рода (нестесняйтесь, если вам нужны некоторые объяснения)

const parentsPartition = _.partition(['ParentId', null], navbar);
const vehicleHierarchy = _.map(
    vehicle => {
        const children = _.filter(['ParentId', vehicle.Id], parentsPartition[1]);
        return _.cond([
            [_.isEmpty, _.constant(vehicle)],
            [_.stubTrue, _.set('children', _, vehicle)]
        ])(children);
    },
    _.concat(parentsPartition[0], newvehicles)
);

И вот результат (извините, мой экран недостаточно высок для полной печати)

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...