Search code examples
javascriptjqueryarrays

Merge array using sum


I am trying to merge/filter an array by shop name and it's status (group by shop & status), also need to sum it's rent_toaal, latefee_total, amount_total and finally count total_shops.

Required output:

[
  {
    "shop": "Dumka Town",
    "status": "paid",
    "rent_total": 200,
    "latefee_total": 2,
    "amount_total": 202,
    "total_shops": 2
  },
  {
    "shop": "Dumka Town",
    "status": "pending",
    "rent_total": 300,
    "latefee_total": 3,
    "amount_total": 303,
    "total_shops": 3
  },
  {
    "shop": "Goushala road",
    "status": "paid",
    "rent_total": 100,
    "latefee_total": 1,
    "amount_total": 101,
    "total_shops": 1
  },
  {
    "shop": "Goushala road",
    "status": "pending",
    "rent_total": 200,
    "latefee_total": 2,
    "amount_total": 201,
    "total_shops": 2
  },
  {
    "shop": "Shiv Pahad",
    "status": "pending",
    "rent_total": 100,
    "latefee_total": 1,
    "amount_total": 101,
    "total_shops": 1
  }
]

I tried this but it's just filtering by shop name:

var arr = [{
    "shop": "Dumka Town",
    "status": "paid",
    "rent_total": 100,
    "latefee_total": 1,
    "amount_total": 101
  },
  {
    "shop": "Dumka Town",
    "status": "paid",
    "rent_total": 100,
    "latefee_total": 1,
    "amount_total": 101
  },
  {
    "shop": "Dumka Town",
    "status": "pending",
    "rent_total": 100,
    "latefee_total": 1,
    "amount_total": 101
  },
  {
    "shop": "Dumka Town",
    "status": "pending",
    "rent_total": 100,
    "latefee_total": 1,
    "amount_total": 101
  },
  {
    "shop": "Dumka Town",
    "status": "pending",
    "rent_total": 100,
    "latefee_total": 1,
    "amount_total": 101
  },
  {
    "shop": "Goushala road",
    "status": "pending",
    "rent_total": 100,
    "latefee_total": 1,
    "amount_total": 101
  },
  {
    "shop": "Goushala road",
    "status": "paid",
    "rent_total": 100,
    "latefee_total": 1,
    "amount_total": 101
  },
  {
    "shop": "Goushala road",
    "status": "pending",
    "rent_total": 100,
    "latefee_total": 1,
    "amount_total": 100
  },
  {
    "shop": "Shiv Pahad",
    "status": "pending",
    "rent_total": 100,
    "latefee_total": 1,
    "amount_total": 101
  }
]

var result = [];

res.forEach(function(a) {
  if (!this[a.area, a.status]) {
    this[a.area] = {
      area: a.area,
      status: a.status,
      rent_total: 0,
      latefee_total: 0,
      amount_total: 0
    };
    result.push(this[a.area]);
  } else {
    this[a.area].rent_total += a.rent_total;
    this[a.area].latefee_total += a.latefee_total;
    this[a.area].amount_total += a.amount_total;
  }
}, Object.create(null));

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


Solution

  • You are missing taking both the shop name and the status into consideration when grouping the data and also add a total to keep track of the total number of shops

    const arr = [
      {
        "shop": "Dumka Town",
        "status": "paid",
        "rent_total": 100,
        "latefee_total": 1,
        "amount_total": 101
      },
      {
        "shop": "Dumka Town",
        "status": "paid",
        "rent_total": 100,
        "latefee_total": 1,
        "amount_total": 101
      },
      {
        "shop": "Dumka Town",
        "status": "pending",
        "rent_total": 100,
        "latefee_total": 1,
        "amount_total": 101
      },
      {
        "shop": "Dumka Town",
        "status": "pending",
        "rent_total": 100,
        "latefee_total": 1,
        "amount_total": 101
      },
      {
        "shop": "Dumka Town",
        "status": "pending",
        "rent_total": 100,
        "latefee_total": 1,
        "amount_total": 101
      },
      {
        "shop": "Goushala road",
        "status": "pending",
        "rent_total": 100,
        "latefee_total": 1,
        "amount_total": 101
      },
      {
        "shop": "Goushala road",
        "status": "paid",
        "rent_total": 100,
        "latefee_total": 1,
        "amount_total": 101
      },
      {
        "shop": "Goushala road",
        "status": "pending",
        "rent_total": 100,
        "latefee_total": 1,
        "amount_total": 100
      },
      {
        "shop": "Shiv Pahad",
        "status": "pending",
        "rent_total": 100,
        "latefee_total": 1,
        "amount_total": 101
      }
    ]
    
    let result = [];
    arr.forEach(function (a) {
        let key = a.shop + '|' + a.status; // Combined shop name and status as key
        if (!this[key]) {
            this[key] = { 
                shop: a.shop, 
                status: a.status, 
                rent_total: 0, 
                latefee_total: 0, 
                amount_total: 0,
                total_shops: 0  // Added total_shops field
            };
            result.push(this[key]);
        }
        this[key].rent_total += a.rent_total;
        this[key].latefee_total += a.latefee_total;
        this[key].amount_total += a.amount_total;
        this[key].total_shops++; // Increment total_shops here
    }, Object.create(null));
    
    console.log(result);