【问题标题】:Consolidate matching elements and iterate and separate out elements non matching elements in a collection合并匹配元素并迭代并分离出集合中不匹配的元素
【发布时间】:2018-11-16 04:01:19
【问题描述】:

我是 Node\JS 的新手,一直坚持如何在收集中合并匹配元素和迭代不匹配元素以创建新集合。到目前为止,我已经使用 lodash 对下面粘贴(分组输入)的数据进行分组,但无法弄清楚如何获得所需的输出。

我愿意使用 lodash\underscore\javascript 或任何其他与 Node 兼容的库。

感谢您的帮助和建议。

Grouped Input:

[ { mod_AccountNumber: '0001',
    mod_Id: '123456',
    mod_LastName: 'SMITH',
    mod_FirstName: 'NANCY',
    mod_AppointmentLocation: 'ROOM10',
    mod_AppointmentDate: '10/26/18',
    mod_AppointmentTime: '0900' },
  { mod_AccountNumber: '0001',
    mod_Id: '123456',
    mod_LastName: 'SMITH',
    mod_FirstName: 'NANCY',
    mod_AppointmentLocation: 'ROOM11',
    mod_AppointmentDate: '10/26/18',
    mod_AppointmentTime: '0930' },
  { mod_AccountNumber: '0001',
    mod_Id: '654321',
    mod_LastName: 'JONES',
    mod_FirstName: 'NATASHA',
    mod_AppointmentLocation: 'ROOM11',
    mod_AppointmentDate: '10/26/18',
    mod_AppointmentTime: '0930' },
  { mod_AccountNumber: '0001',
    mod_Id: '654321',
    mod_LastName: 'JONES',
    mod_FirstName: 'NATASHA',
    mod_AppointmentLocation: 'ROOM12',
    mod_AppointmentDate: '10/26/18',
    mod_AppointmentTime: '1015' }
]

Desired Output:

[ { mod_AccountNumber: '0001',
    mod_Id: '123456',
    mod_LastName: 'SMITH',
    mod_FirstName: 'NANCY',
    mod_AppointmentLocation_1: 'ROOM10',
    mod_AppointmentTime_1:'0900',
    mod_AppointmentLocation_2: 'ROOM11',
    mod_AppointmentTime_2:'0930' },
  { mod_AccountNumber: '0001',
    mod_Id: '654321',
    mod_LastName: 'JONES',
    mod_FirstName: 'NATASHA',
    mod_AppointmentLocation_1: 'ROOM11',
    mod_AppointmentTime_1:'0930',
    mod_AppointmentLocation_2: 'ROOM12',
    mod_AppointmentTime_2:'1015' }
]

【问题讨论】:

  • 你还在坚持那种输出格式吗?通常,当您想使用带有数字的变量名时,例如mod_AppointmentTime_1mod_AppointmentTime_2,您应该使用数组。

标签: javascript node.js underscore.js lodash


【解决方案1】:
const {groupBy, values, merge} = require('lodash');
// input...
const output = values(
    groupBy(input, 'id')
).map(chunks => merge(...chunks));

【讨论】:

  • 不鼓励仅使用代码的答案 - 尝试添加一些解释。此外,这不会产生所需的格式它会丢弃匹配的键,如mod_AppointmentLocation
【解决方案2】:

整体上更好的方法是将这些日期/时间/位置转换为数组。但是鉴于当前的问题可以这样做:

const data = [{ mod_AccountNumber: '0001', mod_Id: '123456', mod_LastName: 'SMITH', mod_FirstName: 'NANCY', mod_AppointmentLocation: 'ROOM10', mod_AppointmentDate: '10/26/18', mod_AppointmentTime: '0900' }, { mod_AccountNumber: '0001', mod_Id: '123456', mod_LastName: 'SMITH', mod_FirstName: 'NANCY', mod_AppointmentLocation: 'ROOM11', mod_AppointmentDate: '10/26/18', mod_AppointmentTime: '0930' }, { mod_AccountNumber: '0001', mod_Id: '654321', mod_LastName: 'JONES', mod_FirstName: 'NATASHA', mod_AppointmentLocation: 'ROOM11', mod_AppointmentDate: '10/26/18', mod_AppointmentTime: '0930' }, { mod_AccountNumber: '0001', mod_Id: '654321', mod_LastName: 'JONES', mod_FirstName: 'NATASHA', mod_AppointmentLocation: 'ROOM12', mod_AppointmentDate: '10/26/18', mod_AppointmentTime: '1015' } ]

const result = _(data)
 .groupBy('mod_Id')
 .values()
 .map(x => _.values(_.transform(x, (r,c,i) => {
   r[c.mod_Id] = _.extend(r[c.mod_Id], {
   mod_Id: c.mod_Id,
   mod_AccountNumber: c.mod_AccountNumber,
   mod_LastName: c.mod_LastName,
   mod_FirstName: c.mod_FirstName,
   [`mod_AppointmentLocation${i+1}`]: c.mod_AppointmentLocation,
   [`mod_AppointmentDate${i+1}`]: c.mod_AppointmentDate,
   [`mod_AppointmentTime${i+1}`]: c.mod_AppointmentTime,
 })}, {})))
 .flatten()
 .value()

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

我们的想法是首先按mod_Id 分组,然后将values map 通过它们和transform 他们带到一个对象。由于您回到了对象形式,您将获得 values 和最后一个 flatten 数组。

更简单的方法是使用 ES6 像这样:

const data = [{ mod_AccountNumber: '0001', mod_Id: '123456', mod_LastName: 'SMITH', mod_FirstName: 'NANCY', mod_AppointmentLocation: 'ROOM10', mod_AppointmentDate: '10/26/18', mod_AppointmentTime: '0900' }, { mod_AccountNumber: '0001', mod_Id: '123456', mod_LastName: 'SMITH', mod_FirstName: 'NANCY', mod_AppointmentLocation: 'ROOM11', mod_AppointmentDate: '10/26/18', mod_AppointmentTime: '0930' }, { mod_AccountNumber: '0001', mod_Id: '654321', mod_LastName: 'JONES', mod_FirstName: 'NATASHA', mod_AppointmentLocation: 'ROOM11', mod_AppointmentDate: '10/26/18', mod_AppointmentTime: '0930' }, { mod_AccountNumber: '0001', mod_Id: '654321', mod_LastName: 'JONES', mod_FirstName: 'NATASHA', mod_AppointmentLocation: 'ROOM12', mod_AppointmentDate: '10/26/18', mod_AppointmentTime: '1015' } ]

const result = Object.values(data.reduce((r, c, i) => {
  let _x = r[c.mod_Id] ? r[c.mod_Id]._x : 0
  _x++
  r[c.mod_Id] = Object.assign(r[c.mod_Id] || {}, {
    mod_Id: c.mod_Id,
    mod_AccountNumber: c.mod_AccountNumber,
    mod_LastName: c.mod_LastName,
    mod_FirstName: c.mod_FirstName,
    [`mod_AppointmentLocation${_x}`]: c.mod_AppointmentLocation,
    [`mod_AppointmentDate${_x}`]: c.mod_AppointmentDate,
    [`mod_AppointmentTime${_x}`]: c.mod_AppointmentTime,
    _x
  })
  return r
}, {})).map(({_x, ...rest}) => rest)
console.log(result)

唯一需要注意的是,这种方法并不纯粹,因为它通过使用_x 属性改变对象来跟踪当前项目编号,最后通过map 剥离该属性

如果您想考虑采用数组的想法,那么事情会变得简单得多:

const data = [{ mod_AccountNumber: '0001', mod_Id: '123456', mod_LastName: 'SMITH', mod_FirstName: 'NANCY', mod_AppointmentLocation: 'ROOM10', mod_AppointmentDate: '10/26/18', mod_AppointmentTime: '0900' }, { mod_AccountNumber: '0001', mod_Id: '123456', mod_LastName: 'SMITH', mod_FirstName: 'NANCY', mod_AppointmentLocation: 'ROOM11', mod_AppointmentDate: '10/26/18', mod_AppointmentTime: '0930' }, { mod_AccountNumber: '0001', mod_Id: '654321', mod_LastName: 'JONES', mod_FirstName: 'NATASHA', mod_AppointmentLocation: 'ROOM11', mod_AppointmentDate: '10/26/18', mod_AppointmentTime: '0930' }, { mod_AccountNumber: '0001', mod_Id: '654321', mod_LastName: 'JONES', mod_FirstName: 'NATASHA', mod_AppointmentLocation: 'ROOM12', mod_AppointmentDate: '10/26/18', mod_AppointmentTime: '1015' } ]

const result = _.chain(data)
  .reduce((r,c,i) => {
  r[c.mod_Id] = r[c.mod_Id] ? r[c.mod_Id] : {
    mod_Id: c.mod_Id,
    mod_AccountNumber: c.mod_AccountNumber,
    mod_LastName: c.mod_LastName,
    mod_FirstName: c.mod_FirstName,
    schedule: []
  }
  r[c.mod_Id].schedule.push({
    mod_AppointmentLocation: c.mod_AppointmentLocation,
    mod_AppointmentDate: c.mod_AppointmentDate,
    mod_AppointmentTime: c.mod_AppointmentTime
  })
  return r
 }, {})
 .values()
 .value()
 
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

【讨论】:

  • 感谢 Akrion 的详细建议。我更喜欢数组的想法,并决定使用它。当我剪切并粘贴您提供的代码时,如果得到“计划:[[对象],[对象]]”。我仔细检查了所有内容:我正在使用 Node with lodash 4.17.11 [ { mod_Id: '123456', mod_AccountNumber: '0001', mod_LastName: 'SMITH', mod_FirstName: 'NANCY', schedule: [[Object], [Object ] ] }, { mod_Id: '654321', mod_AccountNumber: '0001', mod_LastName: 'JONES', mod_FirstName: 'NATASHA', 日程安排: [[Object], [Object] ] } ]
  • 这似乎对我有用...这里是 jsFiddle:jsfiddle.net/akrion/2ekbnwoq
  • 谢谢!在我发表评论之前,我用 JSBin 检查了它,它也可以在那里工作。有趣的是,Node JS 中完全相同的代码会产生 [object object]。我什至将 lodash 降级到 4.17.10。
  • 很奇怪。我也在 Repl 中获得了工作代码:repl.it/@akrion/arrayNodeJSSample
  • 感谢 Akiron。感谢您的所有帮助。你的代码很适合我。
猜你喜欢
  • 1970-01-01
  • 2012-11-24
  • 2014-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-07
  • 1970-01-01
相关资源
最近更新 更多