Это функциональный (ES6) подход:
data.reduce((a,c) => { Object.keys(c).map(k => a[k] = a[k] ? [...a[k],c[k]] : [c[k]]); return a; }, {})
Хотя я бы не стал ставить на повышение производительности по сравнению с императивным подходом в случае JavaScript.
[Обновление]
Вот императив, который является «наиболее близким» к описанному выше функционалу:
result = { }
for(var e of DATA){
for(var p in e){
if(result[p]) { result[p].push(e[p]) } else { result[p] = [e[p]] }
}
}
Как вы могли заметить, мои предложенные решения не имеют каких-либо предварительных представлений об объектах в массиве- как иметь ту же структуру.Это приводит к некоторым накладным расходам при проверке свойства в результате.
Но, как я подозревал и как я уже заметил в некоторых сценариях, функциональная сторона JavaScript на самом деле не разработана с точки зрения производительности.
Но я хотел увидеть себя, поэтому я протестировал два приведенных выше фрагмента здесь: https://jsperf.com/ao-to-oa-imp-func/1
И результаты для меня более чем убедительны: функциональный код работает на 93% медленнеечем в моем Chrome, и на 99% медленнее в Firefox.