Lodash - 为父母使用N(重复)键的儿童

时间:2017-09-28 01:36:05

标签: javascript ecmascript-6 lodash

我从数据库中选择基本上连接主实体和子实体,如下面的示例(汽车与零件)作为片段

我想按汽车零件的所有按键进行分组,并有一系列零件,但包括汽车和零件的所有按键。对于groupBy我可以找到的例子,通常它使用groupBy,但它只对一个键组合。我能够使用大量的解决方法,但我确信使用es6或lodash可以实现相同的可管理性(并获得更高的性能)。

有人可以帮我解决这个问题吗?我尝试过多个groupBy并减少组合,但无法正确链接。



var data =     [{id: 'car1',
name: 'name for car 1',
description: 'description for car1',
partId: 'partId1',
partName: 'partName1'},
  
{id: 'car1',
name: 'name for car 1',
description: 'description for car1',
partId: 'partId2',
partName: 'partName2'},

{id: 'car2',
name: 'name for car 2',
description: 'description for car2',
partId: 'partId3',
partName: 'partName3'},

{id: 'car2',
name: 'name for car 2',
description: 'description for car2',
partId: 'partId4',
partName: 'partName4'}
];
   var dictionary = {};
 data.forEach(function(item, index, array)
  {
    var masterDocument = null;
    if (typeof dictionary[item.id] === 'undefined')
    {
      masterDocument = {
        id: item.id,
        name: item.name,
        description: item.description,
        parts: []
      };
      dictionary[item.id] = masterDocument;
    }
    else {
      var masterDocument = dictionary[item.id];
    }
    masterDocument.parts.push({
      partId: item.partId,
      partName: item.partName
    })
  })


  var asList = [];
  Object.keys(dictionary).forEach((item) => {
    asList.push(dictionary[item])
  });
  console.log(asList);

.as-console-wrapper {
  min-height: 100%;
  top: 0;
}




这里是我想要实现的结果的片段。



[
  {
    "id": "car1",
    "name": "name for car 1",
    "description": "description for car1",
    "parts": [
      {
        "partId": "partId1",
        "partName": "partName1"
      },
      {
        "partId": "partId2",
        "partName": "partName2"
      }
    ]
  },
  {
    "id": "car2",
    "name": "name for car 2",
    "description": "description for car2",
    "parts": [
      {
        "partId": "partId3",
        "partName": "partName3"
      },
      {
        "partId": "partId4",
        "partName": "partName4"
      }
    ]
  }
]




2 个答案:

答案 0 :(得分:2)

以下代码可以使用Lodash解决您的问题。基本上你想要做的是:

  1. id
  2. 对汽车进行分组
  3. 按照ID分组汽车后,使用地图调用迭代该顶级数组,然后从第一个条目中抓取idnamedescription (因为你知道这组中的所有车都是一样的)。保存这些以供稍后返回对象
  4. 然后,在仍处于此顶级地图迭代中的同时,还会迭代每个carGrouping(嵌套地图)中的各个车辆,以获取他们的partIdpartName,然后将其放入{ {1}}数组
  5. 最后,获取所有对象属性,将它们全部放入顶级地图调用中的返回对象中,然后将它们全部返回
  6. 请勿忘记在链条末尾拨打parts以启动Lodash序列
  7. 
    
    valueOf()
    
    let data =  [{id: 'car1',
    name: 'name for car 1',
    description: 'description for car1',
    partId: 'partId1',
    partName: 'partName1'},
    
    {id: 'car1',
    name: 'name for car 1',
    description: 'description for car1',
    partId: 'partId2',
    partName: 'partName2'},
    
    {id: 'car2',
    name: 'name for car 2',
    description: 'description for car2',
    partId: 'partId3',
    partName: 'partName3'},
    
    {id: 'car2',
    name: 'name for car 2',
    description: 'description for car2',
    partId: 'partId4',
    partName: 'partName4'}
    ];
    
    const carsInfo = _(data)
        .groupBy('id')
        .map(carGrouping => {
          // all cars in this array have the same id, name, description, so just grab them from the first one
          const firstCarInGroup = _.first(carGrouping); 
          const id = firstCarInGroup.id;
          const name = firstCarInGroup.name;
          const description = firstCarInGroup.description;
    
          // do a nested map call to iterate over each car in the carGrouping, and grab their partId and partName, and return it in an object
          const parts = _.map(carGrouping, car => {
            return {
              partId: car.partId,
              partName: car.partName
            }
          });
    
          return {
            id,
            name,
            description,
            parts
          }
        })
        .valueOf();
    
    
        console.log(carsInfo);
    
    
    

答案 1 :(得分:2)

这个不使用依赖项。简单的ES6 +。



const data = [{
    id: 'car1',
    name: 'name for car 1',
    description: 'description for car1',
    partId: 'partId1',
    partName: 'partName1'
  },
  {
    id: 'car1',
    name: 'name for car 1',
    description: 'description for car1',
    partId: 'partId2',
    partName: 'partName2'
  },
  {
    id: 'car2',
    name: 'name for car 2',
    description: 'description for car2',
    partId: 'partId3',
    partName: 'partName3'
  },
  {
    id: 'car2',
    name: 'name for car 2',
    description: 'description for car2',
    partId: 'partId4',
    partName: 'partName4'
  }
];

const nested = data.reduce((acc, part) => {
  let index = acc.findIndex(car => car.id === part.id)
  const { partId, partName, ...car } = part

  if (index === -1) {
    acc.push({
      ...car,
      parts: [],
    })

    index = acc.length - 1
  }

  acc[index].parts.push({
    partId,
    partName,
  })

  return acc
}, [])

console.log(JSON.stringify(nested, null, '  '));