skip to Main Content

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

I know it’s easy for you guys, help me achieving this.
Thanks for your valuable time in advance

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
  }
]
`

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 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);

I need short code to achieve this

2

Answers


  1. 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

    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 = [];
    arr.forEach(function (a) {
        var 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);
    Login or Signup to reply.
  2. You may find it easier to create a dictionary using the shop/status values as keys…

    { 'Dumka Town-paid': {...}, 'Dumka Town-pending': {...} ...}
    

    …and then you can update the objects associated with those keys on each iteration.


    Perhaps: reduce over the array of data, build up a dictionary of new/updated objects using the shop/status values as keys, and then extract those objects into a new array with Object.values.

    const data=[{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}];
    
    // Initial object settings
    const initialObj = {
      rent_total: 0,
      latefee_total: 0,
      amount_total: 0,
      shop_total: 0
    };
    
    // Using an empty object as the accumulator for each
    // object in the array...
    const dict = data.reduce((acc, c) => {
    
      // Destructure its shop and status
      const { shop, status } = c;
      
      // Use that as an object key
      const key = `${shop}-${status}`;
      
      // If an object doesn't already exist as the value
      // of that key on the accumulator create one using
      // the current object, and the initial object settings
      acc[key] ??= { ...c, ...initialObj };
      
      // Then update the values using the object's
      // values
      acc[key].rent_total += c.rent_total;
      acc[key].latefee_total += c.latefee_total;
      acc[key].amount_total += c.amount_total;
      acc[key].shop_total += 1;
      
      // Return the accumulator for the next iteration
      return acc;
    }, {});
    
    // Our output from the reduce is an object containing
    // a set of objects as its values, so we just need to
    // extract those values into its own array:
    console.log(Object.values(dict));

    Additional documentation

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search