【问题标题】:Compare objects in one array of objects比较一组对象中的对象
【发布时间】:2018-02-15 16:04:08
【问题描述】:

服务器给了我下一个数组:

let reportsInDB = [
  {comment:"asdasd", date:"13-02-2018", issueId:"1005"},
  {comment:"asdasd", date:"14-02-2018", issueId:"1005"},
  {comment:"asdasd", date:"15-02-2018", issueId:"1005"},
  {comment:"qwe", date:"13-02-2018", issueId:"1006"},
  {comment:"asd123123asd", date:"14-02-2018", issueId:"1006"},
  {comment:"asd123123asd", date:"15-02-2018", issueId:"1006"},
  {comment:"lalala", date:"15-02-2018", issueId:"1007"},
]

有没有办法制作下一个:

比较具有今天日期的对象是否与“昨天”对象具有相同的注释(当然该对象的相同 issueId)并将其推送(可能不是推送整个对象,只是推送 issueId)到新数组,arrRisk = [] for例如,但如果 cmet 连续 3 天相同 - 推送到另一个数组,例如 arrIncident = []。

所以最终的输出应该类似于下一个:

arrRisk = ["1006"]
arrIncident = ["1005]

issueId 为 1007 的对象不应转到任何新数组,因为昨天或前天没有与其 issueId 相同的注释。

我还得到了服务变量,这应该有助于比较:

today = "15-02-2018"
yesterday = "14-02-2018"
beforeYesterday = "13-02-2018"

我正在尝试类似的东西

reportsInDB.map(x => {
    reportsInDB.map(r =>{
    if( x.date === today && 
        r.date === yesterday && 
        x.issueId === r.issueId && 
        x.comment === r.comment
    ){
        reportsToRisk.push(r)
    } 
  })
})

但输出完全不是我需要的(例如,我不需要将 issueId 1005 推送到 riskArray)并且双三重循环并不是我所知道的那么好......

这就是我在 jsfiddle 中尝试的方法

希望我的解释清楚最终结果应该是什么。

来自服务器的排序方式:

【问题讨论】:

  • 如果使用.map()时没有return,那么.map()是错误的方法
  • @Andreas 我明白了.. 我用map() 只是为了循环..
  • .reduce 是要走的路。您需要帮助编写它吗?
  • @Andrew 我认为站在.reduce 一边,但不知道如何实现它,所以如果你能提供帮助,那就太好了!
  • 你的数据能保证按issueId和date排序吗?

标签: javascript arrays object underscore.js


【解决方案1】:

您需要注意另一个问题的相同评论不会起作用。这是一个解决方案,它首先按问题对数据进行分组,然后收集每个问题的 cmets。然后就很简单了。这也不依赖于特定的排序顺序:

const reportsToRisk = [];
const reportsToIncident = [];
const tdy = moment().format('DD-MM-YYYY');
const yst = moment().subtract(1, 'day').format('DD-MM-YYYY');
const dby = moment().subtract(2, 'day').format('DD-MM-YYYY');
const reportsInDB = [
    {comment:"asdasd", date: dby, issueId:"1005"},
    {comment:"asdasd", date: yst, issueId:"1005"},
    {comment:"asdasd", date: tdy, issueId:"1005"},
    {comment:"qwe", date: dby, issueId:"1006"},
    {comment:"asd123123asd", date: yst, issueId:"1006"},
    {comment:"asd123123asd", date: tdy, issueId:"1006"},
    {comment:"123d", date: tdy, issueId:"1007"},
];

// create a map keyed by issueId:
const map = new Map(reportsInDB.map( report => [report.issueId, {}] ));
// Fill the date / comment pairs
for (const report of reportsInDB) {
    map.set(report.issueId, Object.assign(map.get(report.issueId), 
            { [report.date]: report.comment }));
}
for (const [issueId, comments] of map.entries()) {
    if (comments[tdy] === comments[yst]) {
        if (comments[tdy] === comments[dby]) {
            reportsToIncident.push(issueId);
        } else {
            reportsToRisk.push(issueId);
        }
    }
}
//console.log("reportsInDB", reportsInDB)
console.log('reportsToRisk', reportsToRisk)
console.log('reportsToIncident', reportsToIncident)        
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.15.0/moment.min.js"></script>

【讨论】:

    【解决方案2】:

    使用.reduce 反复比较之前的条目。请注意,我使用reportsInDB.slice(1) 作为数组,而.reduce。这使得变量respostInDB[idx] 始终指向数组中的前一个条目。

    之后,运行一个循环来检查新数组中的重复。重复意味着您连续发生 2 次事件。

    在那之后,我必须.filter 删除arrRisk 中也存在于arrIncident 中的ID。

    let reportsInDB = [
      {comment:"asdassd", date:"13-02-2018", issueId:"1005"},
      {comment:"asdasd", date:"14-02-2018", issueId:"1005"},
      {comment:"asdasd", date:"15-02-2018", issueId:"1005"},
      {comment:"qwe", date:"13-02-2018", issueId:"1006"},
      {comment:"asd123123asd", date:"14-02-2018", issueId:"1006"},
      {comment:"asd123123asd", date:"15-02-2018", issueId:"1006"},
      {comment:"lalala", date:"14-02-2018", issueId:"1007"},
      {comment:"lalala", date:"15-02-2018", issueId:"1007"},
      {comment:"lalala", date:"15-02-2018", issueId:"1007"}
    ]
    const matches = reportsInDB.slice(1).reduce((acc, obj, idx) => {
      if (reportsInDB[idx].comment === obj.comment) {
        return acc.concat([obj.issueId])
      } else {
        return acc
      }
    }, [])
    
    let arrRisk = []
    let arrIncident = []
    for (let i = 0; i < matches.length; i++) {
      if (matches[i + 1] === matches[i]) {
        arrIncident.push(matches[i])
      } else {
        arrRisk.push(matches[i])
      }
    }
    arrRisk = arrRisk.filter((id) => !arrIncident.includes(id))
    const issues = {arrRisk, arrIncident}
    console.log(issues)

    【讨论】:

    • 非常感谢!但是当我更改数组时 - 没有预期的结果。例如。 fiddle。在 arrRisk 中应该是问题 1005,1006 和 1007,但只有 1006 和 1007 存在。another fiddle 问题 1007 在两个数组 Incident 和 Risks 中双打。MB 你知道为什么吗?
    • 我认为这正是我所需要的!谢谢!
    猜你喜欢
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-17
    • 1970-01-01
    相关资源
    最近更新 更多