我正在努力使用Javascript对象操作来输出所需的结果

时间:2019-07-24 18:40:48

标签: javascript arrays node.js object

我有一个对象数组,希望将其分组为特定的键和格式。

这是我拥有的物体:

      {
         "id": "98765",
         "things": [{
                 "clientId": "123456",
                 "val": "file1",
                 "cmpId": "54353"
             },
             {
                 "clientId": "1234",
                 "val": "file2",
                 "cmpId": "3453"
             },
             {
                 "clientId": "1234",
                 "val": "file3",
                 "cmpId": "5433"
             }
         ]
     };

我的目的是尝试将对象转换为以下格式

{  
"id":"98765",
"things":{  
   "123456":{  
      "54353":{  
         "val":"file1"
      }
   },
   "1234":{  
      "3453":{  
         "val":"file2"
      },
      "5433":{  
         "val":"file3"
      }
   }
}
}

我设法实现了将“ clientId”作为对象的键,但是我正在努力将广告系列ID嵌套在该对象中。 这是我尝试过的代码


     const a = obj.things.reduce((ac, {clientId, ...rest})=> (ac[clientId] = rest, ac), {})
     console.log(a);

这提供了以下格式,该格式显然无法实现cmpId嵌套,但由于clientId是重复项,因此也摆脱了我的一个对象。我对如何在没有可怕的代码实现的情况下实现非常整洁的东西感到迷惑。

{
'1234': { val: 'file3', cmpId: '5433' },
'123456': { val: 'file1', cmpId: '54353' }
}

5 个答案:

答案 0 :(得分:1)

您快到了,您还需要获取cmpId,然后检查是否已经有clientId的对象,下面是一个示例:

const input = {
  "id": "98765",
  "things": [{
      "clientId": "123456",
      "val": "file1",
      "cmpId": "54353"
    },
    {
      "clientId": "1234",
      "val": "file2",
      "cmpId": "3453"
    },
    {
      "clientId": "1234",
      "val": "file3",
      "cmpId": "5433"
    }
  ]
};

input.things = input.things.reduce((a, {
  clientId,
  cmpId,
  ...rest
}) => {
  if (a[clientId]) {
    a[clientId][cmpId] = rest;
  } else {
    a[clientId] = {
      [cmpId]: rest
    };
  }
  return a;
}, {});

console.log(input);

答案 1 :(得分:0)

您已经关闭。使用Array#reduce是正确的方法。您只需要将ac[clientId] = rest更改为所需的结构:

const obj = {
         "id": "98765",
         "things": [{
                 "clientId": "123456",
                 "val": "file1",
                 "cmpId": "54353"
             },
             {
                 "clientId": "1234",
                 "val": "file2",
                 "cmpId": "3453"
             },
             {
                 "clientId": "1234",
                 "val": "file3",
                 "cmpId": "5433"
             }
         ]
     };
     
obj.things = obj.things.reduce( ( res, { clientId, cmpId, ...rest } ) => {
  res[clientId] = { ...res[clientId], [cmpId]: rest };
  return res;
}, { } );

console.log( obj );

答案 2 :(得分:0)

您可以使用.reduce()来映射/合并things属性,如下所示:

const data = { "id": "98765", "things": [{ "clientId": "123456", "val": "file1", "cmpId": "54353" }, { "clientId": "1234", "val": "file2", "cmpId": "3453" }, { "clientId": "1234", "val": "file3", "cmpId": "5433" } ] };

const newData = { id: data.id,
  things: data.things.reduce((out, {clientId, cmpId, ...rest}) => //for each "thing"
    ({...out, [clientId]: {...out[clientId], [cmpId]: rest}})     //Create/merge with existing clientId
  , {})
};
    
console.log(newData);

答案 3 :(得分:0)

尝试使用JSONPath以防万一,目的是通过遍历该对象来获得所需的结果。这是一个出色的工具,基本上可以将整个json转换为XML

答案 4 :(得分:0)

此版本与此处的其他几个版本相似。这样做的目的是避免更改您的原始结构,并允许将这两个级别上的其他属性传递给输出,只关心thingsclientIdcmpId

const transform = ({things, ...rest}) => ({
  ...rest,
  things: things.reduce(
    (a, {clientId, cmpId, ...rest}) => ({...a, [clientId]: {...a[clientId], [cmpId]: rest}}), 
    {}
  )
})

const data = {id: "98765", things: [{clientId: "123456", val: "file1", cmpId: "54353"}, {clientId: "1234", val: "file2", cmpId: "3453"}, {clientId: "1234", val: "file3", cmpId: "5433"}]}

console .log (
  transform (data)
)