用Lodash通过键将一个对象嵌套到另一个对象中

时间:2019-12-13 09:08:32

标签: javascript node.js

我有一系列具有以下格式的事件:

[
    {
        "Id": 20862,
        "Date": "2019-12-13T00:00:00-08:00",
        "StartTime": 1576220400,
        "EndTime": 1576252800,
        "Slots": [...],
        "TotalTime": 8.5,
        "Cost": 0,
        "Area": 29,
        "PersonId": 1,
        "Creator": 1,
        "Created": "2019-12-10T08:17:14-08:00",
        "Modified": "2019-12-11T06:11:18-08:00",
        "OnCost": 0,
        "StartTimeLocalized": "2019-12-13T09:00:00+02:00",
        "EndTimeLocalized": "2019-12-13T18:00:00+02:00",
        "ExternalId": null,
        "ConnectCreator": null,
        "AreaObject": {  ...  }
    }
]

还有另一组人员:

[ { Id: 1,
    DisplayName: 'Lex Luthor',
    ContactObject: { Email: 'lexl@dc.com' } },
  { Id: 406,
    DisplayName: 'Clark Kent',
    ContactObject: { Email: 'clarkk@dc.com' } } ]

我正在寻找一种通过PersonId属性将Person对象合并到Event对象中的方法。 最终,我需要一系列事件,这些事件具有电子邮件地址和指定人员的姓名:

[
    {
        "Id": 20862,
        "Date": "2019-12-13T00:00:00-08:00",
        "StartTime": 1576220400,
        "EndTime": 1576252800,
        "Slots": [...],
        "TotalTime": 8.5,
        "Cost": 0,
        "Area": 29,
        "PersonId": 1,
        "Creator": 1,
        "Created": "2019-12-10T08:17:14-08:00",
        "Modified": "2019-12-11T06:11:18-08:00",
        "OnCost": 0,
        "StartTimeLocalized": "2019-12-13T09:00:00+02:00",
        "EndTimeLocalized": "2019-12-13T18:00:00+02:00",
        "ExternalId": null,
        "ConnectCreator": null,
        "AreaObject": {  ...  },
        "PersonObject":{ 
           Id: 1,
           DisplayName: 'Lex Luthor',
           ContactObject: { Email: 'lexl@dc.com' } }
         }
]

有什么办法可以用Lodash做到这一点吗?

4 个答案:

答案 0 :(得分:1)

对于这样一个简单的问题,我不会使用lodash。如果您不介意更改原始对象,则可以将Map用于O(n)时间复杂度,以及forEach循环:

const events = [{ Id: 20862, Date: '2019-12-13T00:00:00-08:00', StartTime: 1576220400, EndTime: 1576252800, Slots: [], TotalTime: 8.5, Cost: 0, Area: 29, PersonId: 1, Creator: 1, Created: '2019-12-10T08:17:14-08:00', Modified: '2019-12-11T06:11:18-08:00', OnCost: 0, StartTimeLocalized: '2019-12-13T09:00:00+02:00', EndTimeLocalized: '2019-12-13T18:00:00+02:00', ExternalId: null, ConnectCreator: null, AreaObject: {} }]
const people = [{ Id: 1, DisplayName: 'Lex Luthor', ContactObject: { Email: 'lexl@dc.com' }}, { Id: 406, DisplayName: 'Clark Kent', ContactObject: { Email: 'clarkk@dc.com' }}]

const map = new Map(people.map(p => [p.Id, p]))
events.forEach(e => e.PersonObject = map.get(e.PersonId))

console.log(events)

否则,您可以只使用slice并映射事件数组:

const events = [{ Id: 20862, Date: '2019-12-13T00:00:00-08:00', StartTime: 1576220400, EndTime: 1576252800, Slots: [], TotalTime: 8.5, Cost: 0, Area: 29, PersonId: 1, Creator: 1, Created: '2019-12-10T08:17:14-08:00', Modified: '2019-12-11T06:11:18-08:00', OnCost: 0, StartTimeLocalized: '2019-12-13T09:00:00+02:00', EndTimeLocalized: '2019-12-13T18:00:00+02:00', ExternalId: null, ConnectCreator: null, AreaObject: {} }]
const people = [{ Id: 1, DisplayName: 'Lex Luthor', ContactObject: { Email: 'lexl@dc.com' }}, { Id: 406, DisplayName: 'Clark Kent', ContactObject: { Email: 'clarkk@dc.com' }}]

const map = new Map(people.map(p => [p.Id, p]))
const out = events.map(e => ({...e, PersonObject: map.get(e.PersonId)}))

console.log(out)

答案 1 :(得分:1)

我个人认为您可以只使用普通的JavaScript。

我想对科比的答案提出一些建议。

如果您需要在数组中查找大量元素,则可能需要考虑将数组转换为地图。

这是一个小咖喱助手:

  • 指定搜索元素时要使用的键(请参见k
  • 将数组转换为地图(请参见.bind
const findBy = (k, xs) =>
  ((xs, v) => xs.get(v))
    .bind(null, new Map(xs.map(x => [x[k], x])));

您可以用来构建专门的功能:findPersonById

const findPersonById = findBy('Id', persons);

findPersonById(406);
//=> { Id: 406
//=> , DisplayName: 'Clark Kent'
//=> , ContactObject: { Email: 'clarkk@dc.com' }
//=> }

然后您要做的就是在events数组上映射:
(请注意,根据您对问题的评论,我已删除PersonId,因为它已在PersonObject中提供)

const findBy = (k, xs) =>
  ((xs, v) => xs.get(v))
    .bind(null, new Map(xs.map(x => [x[k], x])));

const findPersonById = findBy('Id', persons);

console.log(

  events.map(({PersonId, ...e}) => (
    { ...e
    , PersonObject: findPersonById(PersonId)
    }
  ))

);
<script>
const events =
  [ { "Id": 20862
    , "Date": "2019-12-13T00:00:00-08:00"
    , "StartTime": 1576220400
    , "EndTime": 1576252800
    , "Slots": []
    , "TotalTime": 8.5
    , "Cost": 0
    , "Area": 29
    , "PersonId": 1
    , "Creator": 1
    , "Created": "2019-12-10T08:17:14-08:00"
    , "Modified": "2019-12-11T06:11:18-08:00"
    , "OnCost": 0
    , "StartTimeLocalized": "2019-12-13T09:00:00+02:00"
    , "EndTimeLocalized": "2019-12-13T18:00:00+02:00"
    , "ExternalId": null
    , "ConnectCreator": null
    , "AreaObject": {}
    }
  ];

const persons =
  [ { Id: 1
    , DisplayName: 'Lex Luthor'
    , ContactObject: { Email: 'lexl@dc.com' }
    }
    ,
    { Id: 406
    , DisplayName: 'Clark Kent'
    , ContactObject: { Email: 'clarkk@dc.com' }
    }
  ];
</script>

答案 2 :(得分:0)

您可以使用。..spread运算符,Array.prototype.find()Array.prototype.map()

尝试一下:

let array1 = [{ "Id": 20862, "Date": "2019-12-13T00:00:00-08:00", "StartTime": 1576220400, "EndTime": 1576252800, "Slots": [], "TotalTime": 8.5, "Cost": 0, "Area": 29, "PersonId": 1, "Creator": 1, "Created": "2019-12-10T08:17:14-08:00", "Modified": "2019-12-11T06:11:18-08:00", "OnCost": 0, "StartTimeLocalized": "2019-12-13T09:00:00+02:00", "EndTimeLocalized": "2019-12-13T18:00:00+02:00", "ExternalId": null, "ConnectCreator": null, "AreaObject": {} }]
let array2 = [{ Id: 1, DisplayName: 'Lex Luthor', ContactObject: { Email: 'lexl@dc.com' } }, { Id: 406, DisplayName: 'Clark Kent', ContactObject: { Email: 'clarkk@dc.com' } }]
let res = array1.map((value, index) => {
  return { ...value, PersonObject: (array2.find(x => x.Id === value.PersonId)) }
})
console.log(res);

答案 3 :(得分:-1)

您不需要lodash

const all = [{
  "Id": 20862,
  "Date": "2019-12-13T00:00:00-08:00",
  "StartTime": 1576220400,
  "EndTime": 1576252800,
  "Slots": [],
  "TotalTime": 8.5,
  "Cost": 0,
  "Area": 29,
  "PersonId": 1,
  "Creator": 1,
  "Created": "2019-12-10T08:17:14-08:00",
  "Modified": "2019-12-11T06:11:18-08:00",
  "OnCost": 0,
  "StartTimeLocalized": "2019-12-13T09:00:00+02:00",
  "EndTimeLocalized": "2019-12-13T18:00:00+02:00",
  "ExternalId": null,
  "ConnectCreator": null,
  "AreaObject": {}
}];

const people = [{
    Id: 1,
    DisplayName: 'Lex Luthor',
    ContactObject: {
      Email: 'lexl@dc.com'
    }
  },
  {
    Id: 406,
    DisplayName: 'Clark Kent',
    ContactObject: {
      Email: 'clarkk@dc.com'
    }
  }
];

const result = all.map(v => ({
  ...v,
  PersonObject: people.find(p => p.Id === v.PersonId)
}));

console.log('result', result);

但这是lodash版本

const all = [{
  "Id": 20862,
  "Date": "2019-12-13T00:00:00-08:00",
  "StartTime": 1576220400,
  "EndTime": 1576252800,
  "Slots": [],
  "TotalTime": 8.5,
  "Cost": 0,
  "Area": 29,
  "PersonId": 1,
  "Creator": 1,
  "Created": "2019-12-10T08:17:14-08:00",
  "Modified": "2019-12-11T06:11:18-08:00",
  "OnCost": 0,
  "StartTimeLocalized": "2019-12-13T09:00:00+02:00",
  "EndTimeLocalized": "2019-12-13T18:00:00+02:00",
  "ExternalId": null,
  "ConnectCreator": null,
  "AreaObject": {}
}];

const people = [{
    Id: 1,
    DisplayName: 'Lex Luthor',
    ContactObject: {
      Email: 'lexl@dc.com'
    }
  },
  {
    Id: 406,
    DisplayName: 'Clark Kent',
    ContactObject: {
      Email: 'clarkk@dc.com'
    }
  }
];

const result = _.map(all, v => _.merge(v, {
  PersonObject: _.find(people, p => p.Id === v.PersonId)
}));

console.log('result', result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>