Home > other >  Create new array of arrays from arrays of objects of array , with specific value
Create new array of arrays from arrays of objects of array , with specific value

Time:04-23

I have following data and I want to make a new array of arrays like below with Javascript. I tried to do a loop twice but couldn't get ideal results.

data: (5) [{…}, {…}, {…}, {…}, {…}]
// above data contains below:

[{
  id: 1,
 productName: "Tacos",

 productData: 
 [ { status: 1, ready: 85, total: 262},
   { status: 2, ready: 59, total: 16},
  
   { status: 3, ready: 67, total: 168},

   { status: 4, ready: 42, total: 301},
   { status: 5, ready: 10, total: 266}, 
   { status: 6, ready: 56, total: 220}, 
   { status: 7, ready: 28, total: 173}]  },
{
 id: 2
,
 productName: "Poke",

 productData: 
 [ { status: 1, ready: 85, total: 300},
   { status: 2, ready: 59, total: 150},

   { status: 3, ready: 67, total: 93},
   { status: 4, ready: 42, total: 173},
   { status: 5, ready: 10, total: 266}, 
   { status: 6, ready: 56, total: 98}, 
   { status: 7, ready: 28, total: 121}]  },
 {
 id: 3

 productName: "Sandwich",

 productData: 
 [ { status: 1, ready: 85, total: 141},
   { status: 2, ready: 59, total: 230},

   { status: 3, ready: 67, total: 155},

   { status: 4, ready: 42, total: 167},
   { status: 5, ready: 10, total: 98}, 
   { status: 6, ready: 56, total: 145}, 
   { status: 7, ready: 28, total: 123}]  
 }, 
 {
 id: 4
 productName: “Burrito”,

 productData: 
 [ { status: 1, ready: 85, total: 45},
   { status: 2, ready: 59, total: 62},

   { status: 3, ready: 67, total: 77},

   { status: 4, ready: 42, total: 21},
   { status: 5, ready: 10, total: 33}, 
   { status: 6, ready: 56, total: 85}, 
   { status: 7, ready: 28, total: 35}]  
 }, 
 {
 id: 5

 productName: “Gyoza”,

 productData: 
 [ { status: 1, ready: 85, total: 88},
   { status: 2, ready: 59, total: 83},

   { status: 3, ready: 67, total: 103},

   { status: 4, ready: 42, total: 98},
   { status: 5, ready: 10, total: 99}, 
   { status: 6, ready: 56, total: 120}, 
   { status: 7, ready: 28, total: 96}]  
 }, 
]


Outcome should be like this. Array of arrays which has numbers from each array with same value of status in productData.

[[262, 300, 141, 45, 88], // All numbers, value of total from status: 1 from each array of productData
 [16, 150, 230, 62, 83],  // status: 2
 [168, 301, 93, 155, 77], // status: 3
 ...]

Thank you in advance.

CodePudding user response:

You should use flatMap() in conjunction with reduce().

const input = [
  {
    id: 1,
    productName: "Tacos",
    productData: [
      { status: 1, ready: 85, total: 262 },
      { status: 2, ready: 59, total: 16 },
      { status: 3, ready: 67, total: 168 },
      { status: 4, ready: 42, total: 301 },
      { status: 5, ready: 10, total: 266 },
      { status: 6, ready: 56, total: 220 },
      { status: 7, ready: 28, total: 173 },
    ],
  },
  {
    id: 2,
    productName: "Poke",
    productData: [
      { status: 1, ready: 85, total: 300 },
      { status: 2, ready: 59, total: 150 },
      { status: 3, ready: 67, total: 93 },
      { status: 4, ready: 42, total: 173 },
      { status: 5, ready: 10, total: 266 },
      { status: 6, ready: 56, total: 98 },
      { status: 7, ready: 28, total: 121 },
    ],
  },
  {
    id: 3,
    productName: "Sandwich",
    productData: [
      { status: 1, ready: 85, total: 141 },
      { status: 2, ready: 59, total: 230 },
      { status: 3, ready: 67, total: 155 },
      { status: 4, ready: 42, total: 167 },
      { status: 5, ready: 10, total: 98 },
      { status: 6, ready: 56, total: 145 },
      { status: 7, ready: 28, total: 123 },
    ],
  },
  {
    id: 4,
    productName: "Burrito",
    productData: [
      { status: 1, ready: 85, total: 45 },
      { status: 2, ready: 59, total: 62 },
      { status: 3, ready: 67, total: 77 },
      { status: 4, ready: 42, total: 21 },
      { status: 5, ready: 10, total: 33 },
      { status: 6, ready: 56, total: 85 },
      { status: 7, ready: 28, total: 35 },
    ],
  },
  {
    id: 5,
    productName: "Gyoza",
    productData: [
      { status: 1, ready: 85, total: 88 },
      { status: 2, ready: 59, total: 83 },
      { status: 3, ready: 67, total: 103 },
      { status: 4, ready: 42, total: 98 },
      { status: 5, ready: 10, total: 99 },
      { status: 6, ready: 56, total: 120 },
      { status: 7, ready: 28, total: 96 },
    ],
  },
];

const output = input
  .flatMap((it) => it.productData)
  .reduce((allStatus, curStatus) => {
    allStatus[curStatus.status]
      ? allStatus[curStatus.status].push(curStatus.total)
      : (allStatus[curStatus.status] = [curStatus.total]);
    return allStatus;
  }, {});

console.log(Object.values(output));

First we flatten the array, so we get one huge array containing all productData:

const flattened = input.flatMap((it) => it.productData);

And after that reduce() will use a JavaScript object with the status as a key to collect all the values with the same status. We start off with an empty object and check for each element whether we have encountered that status already. If we have not, we create an array containing this element total value. In case we have we just push() another value to that array.

Last but not least, we only need to get the values of the JavaScript object as we are not interested in the keys. This can be done using Object.values().

// flatten array
const flattened = input.flatMap((it) => it.productData);

// reduce values based on status
const output = flattened.reduce((allStatus, curStatus) => {
  allStatus[curStatus.status]
    ? allStatus[curStatus.status].push(curStatus.total)
    : (allStatus[curStatus.status] = [curStatus.total]);
  return allStatus;
}, {});

// get values of JS object
console.log(Object.values(output));

CodePudding user response:

This can be achieved by mapping the individual values as sub-arrays and then 'zipping' the result.

const input = [{ id: 1, productName: "Tacos", productData: [{ status: 1, ready: 85, total: 262 }, { status: 2, ready: 59, total: 16 }, { status: 3, ready: 67, total: 168 }, { status: 4, ready: 42, total: 301 }, { status: 5, ready: 10, total: 266 }, { status: 6, ready: 56, total: 220 }, { status: 7, ready: 28, total: 173 },], }, { id: 2, productName: "Poke", productData: [{ status: 1, ready: 85, total: 300 }, { status: 2, ready: 59, total: 150 }, { status: 3, ready: 67, total: 93 }, { status: 4, ready: 42, total: 173 }, { status: 5, ready: 10, total: 266 }, { status: 6, ready: 56, total: 98 }, { status: 7, ready: 28, total: 121 },], }, { id: 3, productName: "Sandwich", productData: [{ status: 1, ready: 85, total: 141 }, { status: 2, ready: 59, total: 230 }, { status: 3, ready: 67, total: 155 }, { status: 4, ready: 42, total: 167 }, { status: 5, ready: 10, total: 98 }, { status: 6, ready: 56, total: 145 }, { status: 7, ready: 28, total: 123 },], }, { id: 4, productName: "Burrito", productData: [{ status: 1, ready: 85, total: 45 }, { status: 2, ready: 59, total: 62 }, { status: 3, ready: 67, total: 77 }, { status: 4, ready: 42, total: 21 }, { status: 5, ready: 10, total: 33 }, { status: 6, ready: 56, total: 85 }, { status: 7, ready: 28, total: 35 },], }, { id: 5, productName: "Gyoza", productData: [{ status: 1, ready: 85, total: 88 }, { status: 2, ready: 59, total: 83 }, { status: 3, ready: 67, total: 103 }, { status: 4, ready: 42, total: 98 }, { status: 5, ready: 10, total: 99 }, { status: 6, ready: 56, total: 120 }, { status: 7, ready: 28, total: 96 },], },];

// map single values
const productTotals = input.map(({ productData }) => productData.map(({ total }) => total));

// zip
const result = productTotals[0].map((_, i) => productTotals.map(ts => ts[i]))

console.log(result)

see: From an array of objects, extract value of a property as array and Javascript equivalent of Python's zip function for further discussion on both operations.

  • Related