将对象数组转换为数组数组

4
我希望有人能在这里指点我正确的方向。我有一个数组,其中包含若干个对象,这些对象具有日期、集合和值属性。
我需要在客户端将其转换为一个二维数组,其中每个成员数组都保存以下数据:[ 日期,集合0的值,集合1的值 ]
我正在寻找一种解决方案,可以处理任意数量的“集合”,这是让我感到困惑的部分。任何提出的解决方案可能需要使用jQuery或您使用的其他javascript库集来完成此操作。我对此没有问题,让我们完成它。 :)
请参考下面的初始和最终数据集:

第一个数组仅有两个集合:

var data = [  
    { Date: "2/10/2013", Set: 0, Value: 1 },   
    { Date: "2/10/2013", Set: 1, Value: 0 },   
    { Date: "2/11/2013", Set: 0, Value: 15 },   
    { Date: "2/11/2013", Set: 1, Value: 8 },   
    { Date: "2/12/2013", Set: 0, Value: 12 },    
    { Date: "2/12/2013", Set: 1, Value: 11 },    
    { Date: "2/13/2013", Set: 0, Value: 15 },   
    { Date: "2/13/2013", Set: 1, Value: 19 },   
    { Date: "2/14/2013", Set: 0, Value: 10 },    
    { Date: "2/14/2013", Set: 1, Value: 20 }   
];

var endData = [
    [ "2/10/2013", 1, 0 ],  
    [ "2/11/2013", 15, 8 ],  
    [ "2/12/2013", 12, 11 ],  
    [ "2/13/2013", 15, 19 ],  
    [ "2/14/2013", 10, 20 ]  
];

这里是一个包含3个集合的示例。 例如,如果数据如下:
var data = [
    { Date: "2/10/2013", Set: 0, Value: 1 },   
    { Date: "2/10/2013", Set: 1, Value: 2 },  
    { Date: "2/10/2013", Set: 2, Value: 3 },   
    { Date: "2/11/2013", Set: 0, Value: 10 },  
    { Date: "2/11/2013", Set: 1, Value: 15 },   
    { Date: "2/11/2013", Set: 2, Value: 20 }  
];

返回的数组应该像这样:
var endData = [  
    [ "2/10/2013", 1, 2, 3 ],  
    [ "2/10/2013", 10, 15, 20 ]  
];

任何建议都会受到赞赏。

3
如果可以的话,请考虑将其转换为一个对象,以日期字符串为键。{"2/10/2013": [1,2,3], "2/11/2013": [10,15,20]} - crush
1
我认为原始格式更好。你的最终数组包含两种类型的数据,但从“语法”角度来看,它们应该只包含一种类型。你可以像遍历数组一样轻松地遍历对象,没有任何理由不这样做。 - Blazemonger
那么,你尝试过什么? - Blazemonger
@Blazemonger,它确实需要以那种格式。我不会没有理由地提出这个要求。如果您查看https://developers.google.com/chart/interactive/docs/gallery/barchart 它期望数据作为一个数组的数组,然后将其转换为DataTable。 - iboros
@crush,我已经有了数据,无法改变来自服务器端的数据,但我同意,这会解决我的问题。 :) - iboros
3个回答

4
使用循环和全局变量dat来跟踪列表中的位置:
var endData=[], dat='', row=[];
for (var i=0; i<data.length; i++) {
    var obj=data[i], val=obj.Value;
    if (dat!=obj.Date) {
        if (i) endData.push(row);
        dat = obj.Date;
        row = [dat, val];
    } else {
        row.push(val);
    }
}
endData.push(row); // last one

http://jsfiddle.net/mblase75/rgJbq/


这个代码明显更加简洁,只需要遍历一次数据,所以我想它的性能应该更好。我已经检查过输出结果是正确的。干得好。 - crush
这是否要求在data数组中按日期排序? - crush
@crush 是的,就像 OP 提供的示例一样。 - Blazemonger
我想要反转它,也就是如何在JavaScript中将数组转换为对象数组。 - Parth Savadiya

1
;(function() {
    var data = [  
        { Date: "2/10/2013", Set: 0, Value: 1 },   
        { Date: "2/10/2013", Set: 1, Value: 0 },   
        { Date: "2/11/2013", Set: 0, Value: 15 },   
        { Date: "2/11/2013", Set: 1, Value: 8 },   
        { Date: "2/12/2013", Set: 0, Value: 12 },    
        { Date: "2/12/2013", Set: 1, Value: 11 },    
        { Date: "2/13/2013", Set: 0, Value: 15 },   
        { Date: "2/13/2013", Set: 1, Value: 19 },   
        { Date: "2/14/2013", Set: 0, Value: 10 },    
        { Date: "2/14/2013", Set: 1, Value: 20 }   
    ];

    var endData = {};

    for (var i = 0; i < data.length; ++i) {
        var date = data[i].Date;

        if (endData[date] === undefined)
            endData[date] = [];

        endData[date].push(data[i].Value);
    }

    var finalData = [];

    for (var ed in endData) {
        var a = [ed];

        for (var i = 0; i < endData[ed].length; ++i) {
            a.push(endData[ed][i]);
        }

        finalData.push(a);
    }

    console.log(finalData);
})();

输出结果如下:

var finalData = [
    ["2/10/2013", 1, 0],
    ["2/11/2013", 15, 8],
    ["2/12/2013", 12, 11],
    ["2/13/2013", 15, 19],
    ["2/14/2013", 10, 20]
];

尝试一下。给我一秒钟。 编辑:这个可行!非常感谢。 - iboros
我想要的是反过来的,也就是如何在JavaScript中将数组的数组转换为对象的数组。 - Parth Savadiya

1
var endData = [];
var indexes = {};

for(var i = 0, len = data.length; i < len; i++) {
    if(indexes[data[i].Date] === undefined) {
        indexes[data[i].Date] = endData.length;
        endData.push([data[i].Date]);
    }
    endData[indexes[data[i].Date]][data[i].Set + 1] = data[i].Value;
}

这个也能产生正确的结果,但我不确定它是否也依赖于预先排序的值。 - crush

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接