简体   繁体   English

合并和嵌套javascript对象

[英]Merge and nest javascript objects

I've got two javascript objects, i want to change the structure of one of them and merge the other one into the first one 我有两个javascript对象,我想更改其中一个的结构并将另一个合并到第一个中

I've tied using loops but it doesn't seem to be the best way to do it 我已经使用循环进行了绑定,但这似乎并不是最好的方法

My first object is called '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' } ]

And my second one is called 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 } ] 

What i want to achieve is for the object of newvehicles to be pushed into the navbar as a child of 'new-cars' and also to go through the navbar and move anything that has a ParentId of not null to be moved into that parent object as a child 我要实现的目标是将新车的对象作为“新车”的子项推入导航栏,并通过导航栏移动任何具有不为null的ParentId的东西移动到该父对象中作为一个孩子

I'm currently using a for loop to do some of the changes: 我目前正在使用for循环进行一些更改:

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

But i'm looking for the output to be something like this: 但是我正在寻找这样的输出:

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' }       } ]

The looping logic you presented already seems to be meeting your goal regarding appending the cars logic. 您提出的循环逻辑似乎已经满足您关于追加汽车逻辑的目标。 However, implicit in your request is that there will only be one entry with a slug of 'new-cars'. 但是,您的要求中隐含的是只有一个条目带有“新车”的标签。 If that is true, then consider: 如果是这样,请考虑:

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

Regarding the non-null parentId, you can: 关于非null parentId,您可以:

  • loop backwards through the outer array, 向后循环通过外部数组,
  • within the loop, find any array items that have an id matching the current item's parentId, 在循环中,找到ID匹配当前项目的parentId的所有数组项目,
  • splice out the current item (the child) 拼接当前项目(孩子)
  • load it into the to the retrieved parent's 'child' property, 将其加载到检索到的父级的“子级”属性中,

Here is the code: 这是代码:

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);    
  }
}

In both cases, prefix 'navigation.' 在这两种情况下,都将前缀“导航”。 to 'navbar' and/or 'newvehicles' as necessary. 必要时转到“导航栏”和/或“新车”。

Edit: To deal with the OP's comment below requesting the ability to associate multiple children with a parent. 编辑:要处理OP的以下注释,要求能够将多个子级与父级关联。

In order for the 'child' property to allow multiple children, we would turn it into an array. 为了让'child'属性允许多个孩子,我们将其变成一个数组。 So we would first check to see if the 'child' property exists in the parent. 因此,我们将首先检查父级中是否存在'child'属性。 If not, we create it and set it equal to an empty array. 如果没有,我们将其创建并将其设置为一个空数组。 Then, we push the spliced child object inside the loop: 然后,将拼接的子对象推入循环:

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]);    
  }
}

Consider changing the name of 'child' to 'children' for your needs. 考虑根据需要将“孩子”的名称更改为“孩子”。

Also, be aware that all of this will only work for one level. 另外,请注意,所有这些操作仅适用于一个级别。 If you need multi-level nesting of parents to children, then a simple loop will not suffice. 如果您需要父母对孩子的多层嵌套,那么简单的循环是不够的。 You may want to create a different question in that case. 在这种情况下,您可能想创建一个不同的问题。

Here is a solution based on Lodash-fp 这是基于Lodash-fp的解决方案

This a variant of Lodash library which allows a full functional programming style and makes this kind of tasks so much easier (don't hesitate if you wish some explanations) 这是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)
);

And here the result (sorry, my screen isn't high enough to full print) 这就是结果(对不起,我的屏幕不够高,无法完整打印)

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM