1

I am trying to manipulate the object below i have given here i need to divide the object into multiple objects based on the qty and warehouse properties.

 var response =  [
              {
                "name": "test1",
                "qty": 3,    //divid obj to 3 times as qty haing 3 
                "warehouse": {
                  "india": 2,
                  "Usa": 1
                }
              },
              {
                "name": "test2",
                "qty": 1,
                "warehouse": {
                  "india": 1
                }
              },
              {
                "name": "test3",
                "qty": 1,
                "warehouse": {
                }
              } 
            ]

 // here i am trying to manipulate to get the result 
        const finalResponse = response.map(item=>{
              if((item.qty>=1) && (Object.keys(item.warehouse).length >= 1)){
                const warehouses = item.warehouse;
                const arr=[]
                Object.keys(warehouses).forEach((key)=>{
                  if(warehouses[key]>=1){
                    arr.push(...Array(warehouses[key]).fill({...item,[key]:1}))
                  }
                })
                return arr;
              }
            })

here i am trying to get output below but i am not able fine right solution

         finalResponse =[  {
                          "name": "test1",
                          "qty": 1,
                          "india": 1
                        },
                        {
                          "name": "test1",
                          "qty": 1,
                          "india": 1
                        },
                        {
                          "name": "test1",
                          "qty": 1,
                          "Usa": 1
                        },
                        {
                          "name": "test2",
                          "qty": 1,
                          "india": 1
                        },,
                     {
                        "name": "test3",
                        "qty": 1,
                        "warehouse": { 
                        }
                        } ];
1

3 Answers 3

1

You can easily achieve this result using flatMap, Object.keys, and Array.from

const response = [{
    name: "test1",
    qty: 3, //divid obj to 3 times as qty haing 3
    warehouse: {
      india: 2,
      Usa: 1,
    },
  },
  {
    name: "test2",
    qty: 1,
    warehouse: {
      india: 1,
    },
  },
];

const result = response.flatMap((o) => {
  const country = Object.keys(o.warehouse).flatMap((k) => Array(o.warehouse[k]).fill(k));
  
  return Array.from({ length: o.qty }, (_, i) => ({
    qty: 1,
    name: o.name,
    [country[i]]: 1,
  }));
});

console.log(result)
/* This is not a part of answer. It is just to give the output fill height. So IGNORE IT */
.as-console-wrapper { max-height: 100% !important; top: 0; }


Edited: If flatMap is not supported then you can use reduce

const response = [
  {
    name: "test1",
    qty: 3, //divid obj to 3 times as qty haing 3
    warehouse: {
      india: 2,
      Usa: 1,
    },
  },
  {
    name: "test2",
    qty: 1,
    warehouse: {
      india: 1,
    },
  },
];

const result = response.reduce((acc, curr) => {
  const country = [];
  Object.keys(curr.warehouse).forEach((k) => {
    const result = Array(curr.warehouse[k]).fill(k);
    country.push(...result);
  });

  acc.push(
    ...Array.from({ length: curr.qty }, (_, i) => ({
      qty: 1,
      name: curr.name,
      [country[i]]: 1,
    }))
  );
  return acc;
}, []);

console.log(result);
/* This is not a part of answer. It is just to give the output fill height. So IGNORE IT */
.as-console-wrapper { max-height: 100% !important; top: 0; }


EDITED AGAIN If warehouse is empty then you could do as

var response = [
  {
    name: "test1",
    qty: 3,
    warehouse: {
      india: 2,
      Usa: 1,
    },
  },
  {
    name: "test2",
    qty: 1,
    warehouse: {
      india: 1,
    },
  },
  {
    name: "test3",
    qty: 1,
    warehouse: {},
  },
];

const result = response.reduce((acc, curr) => {
  const country = [];
  Object.keys(curr.warehouse).forEach((k) => {
    const result = Array(curr.warehouse[k]).fill(k);
    country.push(...result);
  });

  acc.push(
    ...Array.from({ length: curr.qty }, (_, i) => {
      const res = {
        qty: 1,
        name: curr.name,
      };
      if (country[i]) res[country[i]] = 1;
      else res.warehouse = {};
      return res;
    })
  );
  return acc;
}, []);

console.log(result);
/* This is not a part of answer. It is just to give the output fill height. So IGNORE IT */
.as-console-wrapper { max-height: 100% !important; top: 0; }

Sign up to request clarification or add additional context in comments.

8 Comments

Thank you ....but flat map is not supported... in my env
@PavanK Why not? .flatMap() is supported by node since v11
@PavanK You should be able to find polyfills for .flatMap() quite easily. The link in this answer mentions such a polyfill at the bottom of the page.
giving error as not supported flatmap... so thats the reson i am trying with map.. could you please help to get that result
@PavanK I've added a second answer with reduce. Have a look...
|
1
const result = []
response.forEach((item) => {
  const { warehouse, qty: _useless, ...rest } = item;
  Object.entries(warehouse).forEach(([key, value]) => {
    const resultItem = {
      ...rest,
      qty: 1, // this is always 1 right?
      [key]: 1, // and this is also 1 always
    }
    result.push(...Array(value).fill(resultItem))
  })
});


// result
[
  { name: 'test1', qty: 1, india: 1 },
  { name: 'test1', qty: 1, india: 1 },
  { name: 'test1', qty: 1, Usa: 1 },
  { name: 'test2', qty: 1, india: 1 }
]

Comments

0

You can try this to define a new array with each warehouse in the array:

var response =  [
              {
                "name": "test1",
                "qty": 3,    //divid obj to 3 times as qty haing 3 
                "warehouse": {
                  "india": 2,
                  "Usa": 1
                }
              },
              {
                "name": "test2",
                "qty": 1,
                "warehouse": {
                  "india": 1
                }
              },
              {
                "name": "test3",
                "qty": 1,
                "warehouse": {
                }
              } 
            ];

let newArray = [] 
for (const item of response) {
 const { name, qty, warehouse } = item;
 const keys = Object.keys(warehouse);
 if (qty > 0 && keys?.length > 0) {
  for (const key of keys) {
    let newItem = { name, qty: 1}
    for (let i = 0; i <= warehouse[key] - 1; i++) {
      newArray = [...newArray, {...newItem, [key]: 1 }]
    }
  }
 } else {
  newArray = [...newArray, item]
 }
}

console.log(newArray)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.