Search code examples
arraysgroovy

sum values of similar key value pairs


I have this array of objects

[
  {
    id: '1109',
    year: 2022,
    amount: 558270
  },
  {
    id: '1109',
    year: 2022,
    amount: 22842680
  },
  {
    id: '1109',
    year: 2021,
    amount: 32342
  },
  {
    id: '1109',
    year: 2020,
    amount: 323111
  }
],
[
  {
    id: '197',
    year: 2019,
    amount: 9000
  },
  {
    id: '197',
    year: 2023,
    amount: 3000
  },
  {
    id: '197',
    year: 2019,
    amount: 2000
  },
  {
    id: '197',
    year: 2020,
    amount: 1000
  }
]

What i am trying to do is adding the amount of the same year and add them to new arr

what I have been doing is

def newVal = [:]
def arr = []
for(int ii=0 ; ii< arr.size(); ii++){
          for(int jj=1 ; jj < arr.size(); jj++){
              if(arr[ii].year == arr[jj].year){
                  newVal.put("id", arr[i].id)
                  newVal.put("year", arr[ii].year)
                  newVal.put("amount", arr[ii].amount + arr[jj].amount)
                  arr.add(newVal)
              }
          }
      }

this is the output i have

[
  { id: '1109', year: 2022, amount: 23400950 },
  { id: '1109', year: 2022, amount: 45685360 },
  { id: '1109', year: 2021, amount: 64684 },
  { id: '1109', year: 2020, amount: 646222 }
]
[
  { id: '197', year: 2019, amount: 11000 },
  { id: '197', year: 2023, amount: 6000 },
  { id: '197', year: 2019, amount: 4000 },
  { id: '197', year: 2020, amount: 2000 }
]

desired output

[
  {
    id: '1109',
    year: 2022,
    amount: 23400950
  },
  {
    id: '1109',
    year: 2021,
    amount: 32342
  },
  {
    id: '1109',
    year: 2020,
    amount: 323111
  }
],
[
  {
    id: '197',
    year: 2019,
    amount: 11000
  },
  {
    id: '197',
    year: 2023,
    amount: 3000
  },
  {
    id: '197',
    year: 2020,
    amount: 1000
  }
]

Solution

  • Not sure what the issue you're seeing is, but if you have the input as described in your question (but in a format that Groovy can parse)

    def input = [
            [
                    [id: '1109', year: 2022, amount: 558270],
                    [id: '1109', year: 2022, amount: 22842680],
                    [id: '1109', year: 2021, amount: 32342],
                    [id: '1109', year: 2020, amount: 323111]
            ],
            [
                    [id: '197', year: 2019, amount: 9000],
                    [id: '197', year: 2023, amount: 3000],
                    [id: '197', year: 2019, amount: 2000],
                    [id: '197', year: 2020, amount: 1000]
            ]
    ]
    

    Then you can just do:

    def result = input.collect {
        it.groupBy { it.year }
          .collect { year, entries ->
              [year: year, id: entries.id[0], amount: entries.amount.sum()]
          }
    }
    

    And result will equal:

    [
      [
        [year:2022, id:1109, amount:23400950],
        [year:2021, id:1109, amount:32342],
        [year:2020, id:1109, amount:323111]
      ],
      [
        [year:2019, id:197, amount:11000],
        [year:2023, id:197, amount:3000],
        [year:2020, id:197, amount:1000]
      ]
    ]
    

    Which I believe is what you are after