从 array 的对象数组创建新的数组数组,具有特定值

Create new array of arrays from arrays of objects of array , with specific value

我有以下数据,我想用 Javascript 创建一个新的数组数组,如下所示。 我尝试了两次循环,但无法获得理想的结果。

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


结果应该是这样的。 数组数组,其中每个数组的数字在 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
 ...]

提前致谢。

你应该使用 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));

首先我们展平数组,所以我们得到一个包含所有 productData:

的巨大数组
const flattened = input.flatMap((it) => it.productData);

之后reduce()将使用一个JavaScript对象,以status为键,收集所有具有相同状态的值。 我们从一个空对象开始,并检查每个元素是否已经遇到该状态。如果还没有,我们将创建一个包含此元素 total 值的数组。如果我们只是 push() 该数组的另一个值。

最后但同样重要的是,我们只需要获取 JavaScript 对象的值,因为我们对键不感兴趣。这可以使用 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));

这可以通过将各个值映射为 sub-arrays 然后 'zipping' 结果来实现。

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)

请参阅:From an array of objects, extract value of a property as array and Javascript equivalent of Python's zip function 以进一步讨论这两个操作。