Home > OS >  Grouping Array element using two properties
Grouping Array element using two properties

Time:06-15

I am attempting to group an array elements ( containing orders details ). here is my array structure :

enter image description here

[{"id":"myid","base":{"brands":["KI", "SA"],"country":"BG","status":"new"}},{"id":"DEC-00500331","base":{"brands":["DEC"],"country":"UK","status":"new"},"psp":{"name":"adyen","status":"paid"}}]

An order is related to a country website, and can contain one or more brands. for example in one order I can have and item from brand1 and an item from brand2.

I need to group these orders, by country and brand so I can have a consolidated array or object.

I can group by country easily :

let groupedDataByCountryAndBrand = _.groupBy(orders.value, 'base.country') 
Object.keys(groupedDataByCountryAndBrand).forEach(key => {
  table.push(
    {
      country : key, //to be reviewd : for the two brands or more in one order 
      new : groupedDataByCountryAndBrand[key].filter( order => (order.base.status === SFCC_STATUS.new
      || SFCC_STATUS.open
      || SFCC_STATUS.completed )).length
    })
})

Here is the result :

enter image description here

Unfortunatly this is not working for me. I need to group the orders by country and brand so that I can count the newly created orders for each brand by country.

Result I am expecting is something like this :

{
  "country" : "FR",
  "brand": "adidas",
  "pending": 4
  "new" : 3,
  "an other status": 5
}

Do you have any idea how I can achieve this ?

I am using lodash with vue component. Thanks.

CodePudding user response:

Here is what you are looking for, without using of any additional libraries:

const data = [{"id":"myid","base":{"orderNumber":"0500332","marketPlaceOrderCode":"","creationDate":"2022-06-14T10:49:10Z","source":"sfcc","brands":["KI", "SA"],"country":"BG","status":"new","totalEuro":12,"currency":"BGN","units":1,"coupons":null,"shipping":{"id":"BG01","name":"Speedy COD","status":"not_shipped"}},"psp":{"name":"payu","method":null,"status":null},"tms":null},{"id":"DEC-00500331","base":{"orderNumber":"id2","marketPlaceOrderCode":"","creationDate":"2022-06-14T10:41:29Z","source":"sfcc","brands":["DEC"],"country":"UK","status":"new","totalEuro":57,"currency":"GBP","units":1,"coupons":null,"shipping":{"id":"ECA_DPD_ST","name":"Standard shipping","status":"not_shipped"}},"psp":{"name":"adyen","method":null,"status":"paid"},"tms":null}];

const rawResult = normalizeData(data);
console.log(makeItReadable(rawResult));

function normalizeData(data) {
  const result = {};

  data.forEach((order) => {
    const orderData = order.base;

    // add country to result (if not exists)
    if (!result[orderData.country]) {
      result[orderData.country] = {};
    }

    orderData.brands.forEach((brand) => {
      // add brand to exact country (if not exists)
      if (!result[orderData.country][brand]) {
        result[orderData.country][brand] = {};
      }

      // add status to exact brand and country (if not exists)
      if (!result[orderData.country][brand][orderData.status]) {
        result[orderData.country][brand][orderData.status] = 0;
      }

      // increment status count
        result[orderData.country][brand][orderData.status];
    });
  });

  return result;
}

function makeItReadable(rawData) {
  const readableResult = [];
  Object.keys(rawData).map((country) => {
    Object.keys(rawData[country]).map((brand) => {
      readableResult.push({country, brand, ...rawData[country][brand]});
    });
  });

  return readableResult;
}

This code will give you the following result:

[
  { country: 'BG', brand: 'KI', new: 1 },
  { country: 'BG', brand: 'SA', new: 1 },
  { country: 'UK', brand: 'DEC', new: 1 }
]
  • Related