用嵌套键和日期键合并对象的最有效方法是什么?

时间:2018-08-01 03:44:41

标签: javascript arrays ecmascript-6 javascript-objects

这是一个示例数据集:

const largeObject = {  
"4249":{  
  "2018-07-25":[  
     {  
        "start":"2016-07-25T14:09:20.453Z",
        "end":"2016-07-25T14:17:52.147Z"
     }
  ]
},
"9939":{  
  "2018-07-25":[  
     {  
        "start":"2016-07-25T00:50:08.768Z",
        "end":"2016-07-25T00:53:16.514Z"
     }
  ]
},
"2149":{  
  "2018-07-25":[  
     {  
        "start":"2016-07-25T00:42:02.569Z",
        "end":"2016-07-25T00:43:07.689Z"
     }
  ]
},
"6929":{  
  "2018-07-24":[  
     {  
        "start":"2016-07-24T00:44:30.479Z",
        "end":"2016-07-24T00:46:41.315Z"
     }
  ]
},
"7930":{  
  "2018-07-24":[  
     {  
        "start":"2016-07-24T00:39:44.152Z",
        "end":"2016-07-24T00:44:05.420Z"
     }
  ]
},
"4796":{  
  "2018-07-22":[  
     {  
        "start":"2016-07-22T12:48:56.169Z",
        "end":"2016-07-22T13:38:28.136Z"
     }
  ]
}
}

我正在尝试找到最有效的方法来达到以下目的:

   const filteredObject = {
 "2018-07-25": [         
     {  
        "start":"2016-07-25T14:09:20.453Z",
        "end":"2016-07-25T14:17:52.147Z"
     },          {  
        "start":"2016-07-25T00:50:08.768Z",
        "end":"2016-07-25T00:53:16.514Z"
     },
     {  
        "start":"2016-07-25T00:42:02.569Z",
        "end":"2016-07-25T00:43:07.689Z"
     }
   ],
"2018-07-24": [         
    {  
        "start":"2016-07-24T00:44:30.479Z",
        "end":"2016-07-24T00:46:41.315Z"
    },
    {  
        "start":"2016-07-24T00:39:44.152Z",
        "end":"2016-07-24T00:44:05.420Z"
    }
  ],
"2018-07-22": [  
     {  
        "start":"2016-07-22T12:48:56.169Z",
        "end":"2016-07-22T13:38:28.136Z"
     }
]    
};

到目前为止,我已经完成了:

const filteredObject = {}
const newArr = []
for(key in largeObject){
  console.log(largeObject[key])  
}

这摆脱了随机字符串,但仍然让我明白了:

{ '2018-07-24': 
[ { start: '2016-07-24T00:44:30.479Z',
    end: '2016-07-24T00:46:41.315Z' } ] }
{ '2018-07-25': 
  [ { start: '2016-07-25T00:50:08.768Z',
      end: '2016-07-25T00:53:16.514Z' } ] }
{ '2018-07-25': 
  [ { start: '2016-07-25T14:09:20.453Z',
      end: '2016-07-25T14:17:52.147Z' } ] }
  { '2018-07-24': 
  [ { start: '2016-07-24T00:39:44.152Z',
      end: '2016-07-24T00:44:05.420Z' } ] }
{ '2018-07-22': 
  [ { start: '2016-07-22T12:48:56.169Z',
      end: '2016-07-22T13:38:28.136Z' } ] }
{ '2018-07-25': 
  [ { start: '2016-07-25T00:42:02.569Z',
      end: '2016-07-25T00:43:07.689Z' } ] }

这是我所知道的。我仍然需要找到一种方法来合并所有具有相同键值的数组。似乎我需要遍历此对象,将日期保留为键,并将与该日期键关联的所有数组推入一个数组。

处理这样的事情的最佳方法是什么?我还希望尽可能高效地执行此操作,而不必在每次检查日期键和/或将开始/结束对象放入其自己的数组时都遍历整个大对象。

1 个答案:

答案 0 :(得分:2)

您可以从Object.values()原始数据开始。这将为您提供一个值数组,而没有可以使用reduce()的第一级键。然后,将它们分解成一个键和一个值。如果键还没有数组值,请添加它,然后将其合并到数据中。

const largeObject = {  "4249":{  "2018-07-25":[  {  "start":"2016-07-25T14:09:20.453Z","end":"2016-07-25T14:17:52.147Z"}]},"9939":{  "2018-07-25":[  {  "start":"2016-07-25T00:50:08.768Z","end":"2016-07-25T00:53:16.514Z"}]},"2149":{  "2018-07-25":[  {  "start":"2016-07-25T00:42:02.569Z","end":"2016-07-25T00:43:07.689Z"}]},"6929":{  "2018-07-24":[  {  "start":"2016-07-24T00:44:30.479Z","end":"2016-07-24T00:46:41.315Z"}]},"7930":{  "2018-07-24":[  {  "start":"2016-07-24T00:39:44.152Z","end":"2016-07-24T00:44:05.420Z"}]},"4796":{  "2018-07-22":[  {  "start":"2016-07-22T12:48:56.169Z","end":"2016-07-22T13:38:28.136Z"}]}}
    
let filtered = Object.values(largeObject).reduce((a, c) => {
    Object.entries(c).forEach(([k, v]) => {
        (a[k] || (a[k] = [])).push(...v)
    })
    return a
},{})
console.log(filtered)