Home > Back-end >  Merge duplicate objects in array and sum the values
Merge duplicate objects in array and sum the values

Time:08-26

I have an array of objects

    [
      {
        "team": "team-a",
        "results": {
          "passed": 1,
          "failed": 1,
          "flaky": 1,
          "skipped": 1,
          "timedOut": 1
        }
      },
      {
        "team": "team-b",
        "results": {
          "passed": 1,
          "failed": 1,
          "flaky": 1,
          "skipped": 1,
          "timedOut": 1
        }
      },
      {
        "team": "team-a",
        "results": {
          "passed": 1,
          "failed": 1,
          "flaky": 1,
          "skipped": 1,
          "timedOut": 1
        }
      },
      {
        "team": "team-b",
        "results": {
          "passed": 1,
          "failed": 1,
          "flaky": 1,
          "skipped": 1,
          "timedOut": 1
        }
      },
      {
        "team": "team-unassigned",
        "results": {
          "passed": 1,
          "failed": 1,
          "flaky": 1,
          "skipped": 1,
          "timedOut": 1
        }
      }
    ]

I'm looking for a way to merge objects with duplicate team keys and then sum each value in the results object. The final result would look like this:

[
  {
    "team": "team-a",
    "results": {
      "passed": 2,
      "failed": 2,
      "flaky": 2,
      "skipped": 2,
      "timedOut": 2
    }
  },
  {
    "team": "team-b",
    "results": {
      "passed": 2,
      "failed": 2,
      "flaky": 2,
      "skipped": 2,
      "timedOut": 2
    }
  },
  {
    "team": "team-unassigned",
    "results": {
      "passed": 1,
      "failed": 1,
      "flaky": 1,
      "skipped": 1,
      "timedOut": 1
    }
  }
]

I've tried reducing but just can't get to the working solution. Could anyone give some pointers?

CodePudding user response:

Have in mind that it modifies source array.

const source = [{
    "team": "team-a",
    "results": {
      "passed": 1,
      "failed": 1,
      "flaky": 1,
      "skipped": 1,
      "timedOut": 1
    }
  },
  {
    "team": "team-b",
    "results": {
      "passed": 1,
      "failed": 1,
      "flaky": 1,
      "skipped": 1,
      "timedOut": 1
    }
  },
  {
    "team": "team-a",
    "results": {
      "passed": 1,
      "failed": 1,
      "flaky": 1,
      "skipped": 1,
      "timedOut": 1
    }
  },
  {
    "team": "team-b",
    "results": {
      "passed": 1,
      "failed": 1,
      "flaky": 1,
      "skipped": 1,
      "timedOut": 1
    }
  },
  {
    "team": "team-unassigned",
    "results": {
      "passed": 1,
      "failed": 1,
      "flaky": 1,
      "skipped": 1,
      "timedOut": 1
    }
  }
]
const additional = [{
    "team": "team-a",
    "results": {
      "passed": 2,
      "failed": 2,
      "flaky": 2,
      "skipped": 2,
      "timedOut": 2
    }
  },
  {
    "team": "team-b",
    "results": {
      "passed": 2,
      "failed": 2,
      "flaky": 2,
      "skipped": 2,
      "timedOut": 2
    }
  },
  {
    "team": "team-unassigned",
    "results": {
      "passed": 1,
      "failed": 1,
      "flaky": 1,
      "skipped": 1,
      "timedOut": 1
    }
  }
]

source.forEach(({
  team,
  results
}) => {
  const {
    results: additionalResults
  } = additional.find(o => o.team === team)
  Object.entries(additionalResults).forEach(([key, value]) => {
    results[key]  = value
  })
})

console.log(source)

CodePudding user response:

Yes reduce and inside of it you group by item.team into the accumulative variable having summing all the numbers in results object.

var arr=[{team:"team-a",results:{passed:1,failed:1,flaky:1,skipped:1,timedOut:1}},{team:"team-b",results:{passed:1,failed:1,flaky:1,skipped:1,timedOut:1}},{team:"team-a",results:{passed:1,failed:1,flaky:1,skipped:1,timedOut:1}},{team:"team-b",results:{passed:1,failed:1,flaky:1,skipped:1,timedOut:1}},{team:"team-unassigned",results:{passed:1,failed:1,flaky:1,skipped:1,timedOut:1}}]

var result = Object.values(arr.reduce(function(agg, item) {
  agg[item.team] = agg[item.team] || {
    team: item.team,
    results: {}
  };
  for (var key in item.results) {
    agg[item.team].results[key] = (agg[item.team].results[key] || 0)   item.results[key]
  }
  return agg;
}, {}))

console.log(result);
.as-console-wrapper {
  max-height: 100% !important;
}

  • Related