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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.