将对象数组重新格式化为键数组

Posted

技术标签:

【中文标题】将对象数组重新格式化为键数组【英文标题】:Reformat an array of objects to an array of key'd arrays 【发布时间】:2018-04-27 18:36:26 【问题描述】:

所以我对 javascript 有点陌生,但我正在尝试将 startArray 重新格式化为 endArray。 startArray 基本上是一个订单对象数组,它们总是有不同的 orderId,但可以有相同的 companyId。我基本上是在尝试切换它,使其基于公司,因此对于每个 companyId,都有所有公司订单的数组。我一直在修补并试图弄清楚这一点,但老实说,我不确定从哪里开始,或者这种操作是否可能。

我正在使用 Google Apps Scripts,我认为它仍然使用 ES5 语法,如果可能的话,我更愿意坚持使用 vanilla javascript。

var startArray = [
    "companyId" : 1,
     "orderId" : 25,
     "product" : "productA"
     "quantity" : 2,
     "price" : 10,
    ,
    "companyId" : 1,
     "orderId" : 20,
     "product" : "productB"
     "quantity" : 3,
     "price" : 5,
    ,
   "companyId" : 2,
     "orderId" : 15,
     "product" : "productA"
     "quantity" : 5,
     "price" : 10,
    
 ]

 var endArray = [ 
      '1' = ["orderId" : 25,
         "product" : "productA"
         "quantity" : 2,
         "price" : 10,,
         "orderId" : 20,
          "product" : "productB"
          "quantity" : 3,
          "price" : 5,
      ,
     '2' = ["orderId" : 15,
          "product" : "productA"
          "quantity" : 5,
          "price" : 10,
         ]
   ]


 ]

【问题讨论】:

您确定希望最终产品是一个数组,而不是一个对象吗?仅仅作为一个由companyId 键索引的对象可能更有意义,而不是一个内部包含单个对象的数组 我认为这也可以!那有可能吗?你的意思是像 1 个对象,每个键都是一个 companyId? 如,结果不是像您发布的endArray,而是像您的endArray[0],因为看起来数组中只有一个项目。 (在这种情况下为什么有一个数组) 【参考方案1】:

使用reduce 之类的东西创建一个新对象,插入一个数组作为companyId 的键(如果它尚不存在):

function reduce(arr, callback, initialVal) 
  var accumulator = (initialVal === undefined) ? undefined : initialVal;
  for (var i = 0; i < arr.length; i++) 
    if (accumulator !== undefined)
      accumulator = callback.call(undefined, accumulator, arr[i], i, this);
    else
      accumulator = arr[i];
  
  return accumulator;


var startArray = [
  "companyId" : 1,
   "orderId" : 25,
   "product" : "productA",
   "quantity" : 2,
   "price" : 10,
  ,
  "companyId" : 1,
   "orderId" : 20,
   "product" : "productB",
   "quantity" : 3,
   "price" : 5,
  ,
  "companyId" : 2,
   "orderId" : 15,
   "product" : "productA",
   "quantity" : 5,
   "price" : 10,
  
];

var endObj = reduce(startArray, function (accum, item) 
  var companyId = item.companyId;
  if (!accum[companyId]) accum[companyId] = [];
  delete item.companyId;
  accum[companyId].push(item);
  return accum;
, );
console.log(endObj);

【讨论】:

效果很好,非常感谢@CertainPerformance!【参考方案2】:

如果您对结果是对象而不是数组感到满意,那么这应该可以完成工作:

var startArray = [
    "companyId" : 1,
     "orderId" : 25,
     "product" : "productA",
     "quantity" : 2,
     "price" : 10,
    ,
    "companyId" : 1,
     "orderId" : 20,
     "product" : "productB",
     "quantity" : 3,
     "price" : 5,
    ,
   "companyId" : 2,
     "orderId" : 15,
     "product" : "productA",
     "quantity" : 5,
     "price" : 10,
    
 ];

var ret = 

startArray.forEach(company => 
  if (!ret[company.companyId]) 
    ret[company.companyId] = [];
  
  
  ret[company.companyId].push(company);
);

console.log(ret);

如果您没有 ES6 支持,只需使用经典的 for in 循环而不是 forEach

【讨论】:

Apps Script 是带有一些附加功能的 JS 1.6 - 其中之一是 Array#forEach

以上是关于将对象数组重新格式化为键数组的主要内容,如果未能解决你的问题,请参考以下文章

jOOQ JSON 格式化为对象数组

将对象数组的数组简化为对象数组

built_value 如何将 json 数组反序列化为对象数组?

无法将 JSON 数组反序列化为 C# 对象 [关闭]

JSON 对象未正确格式化为 Javascript

如何将对象的json数组反序列化为字典[重复]