在JavaScript中转置对象数组

在JavaScript中转置对象数组,javascript,jquery,arrays,Javascript,Jquery,Arrays,我试图在JavaScript中转置一个对象数组 我有一组对象: var myData=[ {“班次”:“1”,“日期”:“01/01/2016/08/00/00”,“汽车”:“178”,“卡车”:“255”,“自行车”:“317”,“摩托车”:“237”}, {“班次”:“2”,“日期”:“01/01/2016/17/00/00”,“汽车”:“125”,“卡车”:“189”,“自行车”:“445”,“摩托车”:“273”}, {“班次”:“3”,“日期”:“02/01/2016/08/00/0

我试图在JavaScript中转置一个对象数组

我有一组对象:

var myData=[
{“班次”:“1”,“日期”:“01/01/2016/08/00/00”,“汽车”:“178”,“卡车”:“255”,“自行车”:“317”,“摩托车”:“237”},
{“班次”:“2”,“日期”:“01/01/2016/17/00/00”,“汽车”:“125”,“卡车”:“189”,“自行车”:“445”,“摩托车”:“273”},
{“班次”:“3”,“日期”:“02/01/2016/08/00/00”,“汽车”:“140”,“卡车”:“219”,“自行车”:“328”,“摩托车”:“412”},
{“班次”:“4”,“日期”:“02/01/2016/17/00/00”,“汽车”:“222”,“卡车”:“290”,“自行车”:“432”,“摩托车”:“378”},
{“班次”:“5”,“日期”:“03/01/2016/08/00/00”,“汽车”:“200”,“卡车”:“250”,“自行车”:“420”,“摩托车”:“319”},
{“班次”:“6”,“日期”:“03/01/2016/17/00/00”,“汽车”:“230”,“卡车”:“220”,“自行车”:“310”,“摩托车”:“413”},
{“班次”:“7”,“日期”:“04/01/2016/08/00/00”,“汽车”:“155”,“卡车”:“177”,“自行车”:“377”,“摩托车”:“180”},
{“班次”:“8”,“日期”:“04/01/2016/17/00/00”,“汽车”:“179”,“卡车”:“203”,“自行车”:“405”,“摩托车”:“222”},
{“班次”:“9”,“日期”:“05/01/2016/08/00/00”,“汽车”:“208”,“卡车”:“185”,“自行车”:“360”,“摩托车”:“195”},
{“班次”:“10”,“日期”:“05/01/2016/17/00/00”,“汽车”:“150”,“卡车”:“290”,“自行车”:“315”,“摩托车”:“280”},
{“班次”:“11”,“日期”:“06/01/2016/08/00/00”,“汽车”:“200”,“卡车”:“220”,“自行车”:“350”,“摩托车”:“205”},
{“班次”:“12”,“日期”:“06/01/2016/17/00/00”,“汽车”:“230”,“卡车”:“170”,“自行车”:“390”,“摩托车”:“400”}
];
out='';
$。每个(我的数据,函数(ndx,obj){
out+='{';
$。每个(对象、功能(键、值){
out+=键+':'+val+',';
});
out+='}
'; }); $('body')。追加(out)
您想要的结果具有重复的属性,这是不允许的

相反,您可以将该内部结构转换为仅包含值的数组,并将其指定给属性。像这样:

{
  "shift": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"],
  "date": ["01/01/2016/08/00/00", "01/01/2016/17/00/00", // ...etc
}
您可以将此ES6代码用于该转换:

const result = Object.assign(...Object.keys(myData[0]).map( key =>
    ({ [key]: myData.map( o => o[key] ) })
));
var myData=[
{“班次”:“1”,“日期”:“01/01/2016/08/00/00”,“汽车”:“178”,“卡车”:“255”,“自行车”:“317”,“摩托车”:“237”},
{“班次”:“2”,“日期”:“01/01/2016/17/00/00”,“汽车”:“125”,“卡车”:“189”,“自行车”:“445”,“摩托车”:“273”},
{“班次”:“3”,“日期”:“02/01/2016/08/00/00”,“汽车”:“140”,“卡车”:“219”,“自行车”:“328”,“摩托车”:“412”},
{“班次”:“4”,“日期”:“02/01/2016/17/00/00”,“汽车”:“222”,“卡车”:“290”,“自行车”:“432”,“摩托车”:“378”},
{“班次”:“5”,“日期”:“03/01/2016/08/00/00”,“汽车”:“200”,“卡车”:“250”,“自行车”:“420”,“摩托车”:“319”},
{“班次”:“6”,“日期”:“03/01/2016/17/00/00”,“汽车”:“230”,“卡车”:“220”,“自行车”:“310”,“摩托车”:“413”},
{“班次”:“7”,“日期”:“04/01/2016/08/00/00”,“汽车”:“155”,“卡车”:“177”,“自行车”:“377”,“摩托车”:“180”},
{“班次”:“8”,“日期”:“04/01/2016/17/00/00”,“汽车”:“179”,“卡车”:“203”,“自行车”:“405”,“摩托车”:“222”},
{“班次”:“9”,“日期”:“05/01/2016/08/00/00”,“汽车”:“208”,“卡车”:“185”,“自行车”:“360”,“摩托车”:“195”},
{“班次”:“10”,“日期”:“05/01/2016/17/00/00”,“汽车”:“150”,“卡车”:“290”,“自行车”:“315”,“摩托车”:“280”},
{“班次”:“11”,“日期”:“06/01/2016/08/00/00”,“汽车”:“200”,“卡车”:“220”,“自行车”:“350”,“摩托车”:“205”},
{“班次”:“12”,“日期”:“06/01/2016/17/00/00”,“汽车”:“230”,“卡车”:“170”,“自行车”:“390”,“摩托车”:“400”}
];
const result=Object.assign(…Object.keys(myData[0]).map(key=>
({[key]:myData.map(o=>o[key]))
));
控制台日志(结果)

.as console wrapper{max height:100%!important;top:0;}
由于对象不能具有重复的属性,我建议使用与数组相同的属性名来累积值:

函数转置(数据){
让结果={};
for(让数据行){
for(让Object.entries的[key,value](行)){
结果[键]=结果[键]| |[];
结果[键]。推送(值);
}
}
返回结果;
}
//例如:
让数据=[
{“班次”:1,“日期”:“01/01/2016/08/00/00”},
{“班次”:2,“日期”:“01/01/2016/17/00/00”},
{“班次”:3,“日期”:“02/01/2016/08/00/00”}
];

console.log(转置(数据));//{“shift”:[1,2,3],“date”:[…])
用于使用新的
对象的与trincot的oneliner等效的安全类型脚本友好。fromEntries
函数:

const result = Object.fromEntries(Object.keys(myData[0]).map(key => [key, myData.map(o => o[key])]))
把它分解一下:

const keys = Object.keys(myData[0]);
const entries = keys.map(key => [key, myData.map(o => o[key])]);
const result = Object.fromEntries(entries)

如果没有键,则使用Object.assign和spread运算符的原始代码将抛出一个错误,因此TS编译器拒绝包含错误“预期至少1个参数,但得到0或更多”的代码。如果没有键,新代码将导致
{}

对象不能有重复的属性名。感谢gang,我应该看到我要去的地方的基本问题。这适用于d3.js应用程序,其中输入数据csv文件包含列数据,因此无法正确表示。我试图将数据转换成一种面向行的格式,但显然我在这方面工作的时间太长了。谢谢你的建议。如果你需要d3的话,trincot的答案和我的答案都可以
@trincot
更优雅,但是从当前数据中的第一个元素获取密钥,并假设它们都具有相同的结构。如果他们不这样做,就会出错。我的不会,但这对你没有多大帮助,因为d3不会绘制预期的图表(如果任何对象不同)。所以你应该选择trincot的答案。如果要跟踪具有可变结构的对象,必须有一个包含所有属性的单独数组,并使用
shift
作为index/tracker.Eh、@AndreiGheorghiu,我的解决方案不会出错。如果其他行中的属性更少或更多,它只会跳过不在第一个对象中的属性,当其他对象中缺少属性时,用
未定义的
来填补空白。@trincot如果任何对象有属性,而第一个对象没有属性,恐怕会出错。然而,这种情况几乎不可能发生。考虑到它来自一个数据库,我认为你的答案是可靠的,应该是被接受的。这是OP期望的解决方案吗?问题是期望的OP解决方案是不可能的。确切地说。我只是想知道OP是否意识到了这一点,如果是的话-也许最好等他把他的问题准确地说出来(:我们都不一样;-)(顺便说一句,你会说法语吗?)回答得好!我只想加一张便条,告诉你这个限制