Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/399.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在javascript中重构复杂对象数组的最有效方法?_Javascript_Arrays_Json_Object_Dataset - Fatal编程技术网

在javascript中重构复杂对象数组的最有效方法?

在javascript中重构复杂对象数组的最有效方法?,javascript,arrays,json,object,dataset,Javascript,Arrays,Json,Object,Dataset,我有一大组数据,看起来与此类似: var original = [ { country : 'us', date : '2014-10-29', cost : 45.3 }, { country : 'africa', date : '2014-10-29', cost : 60.5 }, { country : 'south_america', date : '2014-10-30', cost : 10 }, { country : 'us', date : '2014-10

我有一大组数据,看起来与此类似:

var original = [
  { country : 'us', date : '2014-10-29', cost : 45.3 },
  { country : 'africa', date : '2014-10-29', cost : 60.5 },
  { country : 'south_america', date : '2014-10-30', cost : 10 },
  { country : 'us', date : '2014-10-30', cost : 30 }
];
我需要重新排列此数据,使其看起来更像:

var newData = [
  { date : '2014-10-29', us : 45.3, africa : 60.5, south_america : 0 },
  { date : '2014-10-30', us : 30, africa : 0, south_america : 10 }
]

我对处理这样的数据集是新手,我正在努力寻找任何有效的方法来处理它。。。我唯一能想到的就是使用多个for循环,而且看起来很恶心。有人有什么想法或建议吗?

首先想到的是这样做

原始变量=[ {国家:'us',日期:'2014-10-29',成本:45.3}, {国家:“非洲”,日期:“2014-10-29”,费用:60.5}, {国家:'南美洲',日期:'2014-10-30',费用:10}, {国家:'us',日期:'2014-10-30',费用:30} ]; var t={}; var结果=[]; 原始。forEachfunctionentry{ var n=t[entry.date]=t[entry.date]|{}; n、 日期=输入日期; n[输入国家]=输入成本; }; forvar k in t{ 如果t.hasOwnPropertyk{ 结果:pusht[k]; } }
console.logresult 第一个想法是这样做

原始变量=[ {国家:'us',日期:'2014-10-29',成本:45.3}, {国家:“非洲”,日期:“2014-10-29”,费用:60.5}, {国家:'南美洲',日期:'2014-10-30',费用:10}, {国家:'us',日期:'2014-10-30',费用:30} ]; var t={}; var结果=[]; 原始。forEachfunctionentry{ var n=t[entry.date]=t[entry.date]|{}; n、 日期=输入日期; n[输入国家]=输入成本; }; forvar k in t{ 如果t.hasOwnPropertyk{ 结果:pusht[k]; } }
console.logresult 不幸的是,解决这个问题的方法是多个循环。您可以通过将可怕的代码放在函数中,然后将该函数隐藏在代码底部,从而让自己感觉更好

Jaromanda的答案是,从内存和时间两个方面来看,it效率更高,但如果您确实拥有大量数据,您应该考虑在服务器上重新组织数据,因为输出数据比原始数据小,因此传输的数据会更少。尽管您可能喜欢将工作量分配给客户的想法

如果您仍然认为重新组织数据客户端是一种可行的方法,那么您可能会喜欢此函数,如果您更改属性名称,此函数很容易使用

function groupAndMerge(original,groupBy,merge){

    var grouped={},list=[];

    original.forEach(function(o){
        var k=o[groupBy];
        if(!grouped[k]) grouped[ k ]=[];
        grouped[k].push(o);
    });

    for(var i in grouped){
        var d={};
        list.push(d);
        grouped[i].forEach(function(o){
            d[groupBy]=i;
            for(var k in merge)     d[o[k]]=o[merge[k]];
        });

    }

    return list;

}

var original = [
  { country : 'us', date : '2014-10-29', cost : 45.3 },
  { country : 'africa', date : '2014-10-29', cost : 60.5 },
  { country : 'south_america', date : '2014-10-30', cost : 10 },
  { country : 'us', date : '2014-10-30', cost : 30 }
];

var result=groupAndMerge(original,'date',{'country':'cost'});

不幸的是,解决这个问题的方法是多个循环。您可以通过将可怕的代码放在函数中,然后将该函数隐藏在代码底部,从而让自己感觉更好

Jaromanda的答案是,从内存和时间两个方面来看,it效率更高,但如果您确实拥有大量数据,您应该考虑在服务器上重新组织数据,因为输出数据比原始数据小,因此传输的数据会更少。尽管您可能喜欢将工作量分配给客户的想法

如果您仍然认为重新组织数据客户端是一种可行的方法,那么您可能会喜欢此函数,如果您更改属性名称,此函数很容易使用

function groupAndMerge(original,groupBy,merge){

    var grouped={},list=[];

    original.forEach(function(o){
        var k=o[groupBy];
        if(!grouped[k]) grouped[ k ]=[];
        grouped[k].push(o);
    });

    for(var i in grouped){
        var d={};
        list.push(d);
        grouped[i].forEach(function(o){
            d[groupBy]=i;
            for(var k in merge)     d[o[k]]=o[merge[k]];
        });

    }

    return list;

}

var original = [
  { country : 'us', date : '2014-10-29', cost : 45.3 },
  { country : 'africa', date : '2014-10-29', cost : 60.5 },
  { country : 'south_america', date : '2014-10-30', cost : 10 },
  { country : 'us', date : '2014-10-30', cost : 30 }
];

var result=groupAndMerge(original,'date',{'country':'cost'});

如果数据已排序,则有一种更快的方法,只使用一个循环:

var output=document.querySelector'output'; 原始变量=[ {国家:'us',日期:'2014-10-29',成本:45.3}, {国家:“非洲”,日期:“2014-10-29”,费用:60.5}, {国家:'南美洲',日期:'2014-10-30',费用:10}, {国家:'us',日期:'2014-10-30',费用:30} ]; 函数mapDatadata{ var newData=[]; var newMap={}; newMap.date=数据[0]。日期; 对于变量i=0;i如果数据已排序,则有一种更快的方法,只使用一个循环:

var output=document.querySelector'output'; 原始变量=[ {国家:'us',日期:'2014-10-29',成本:45.3}, {国家:“非洲”,日期:“2014-10-29”,费用:60.5}, {国家:'南美洲',日期:'2014-10-30',费用:10}, {国家:'us',日期:'2014-10-30',费用:30} ]; 函数mapDatadata{ var newData=[]; var newMap={}; newMap.date=数据[0]。日期; 对于变量i=0;i通过使用字典存储指向与给定日期关联的条目索引的指针,可以限制中间集合的创建。带有reduce函数的示例,没有任何for循环

原始变量=[ {国家:'us',日期:'2014-10-29',成本:45.3}, {国家:“非洲”,日期:“2014-10-29”,费用:60.5}, {国家:'南美洲',日期:'2014-10-30',费用:10}, {国家:'us',日期:'2014-10-30',费用:30} ]; var newData=original.reducefunctionacc,d{ var日期=d日期; var idx=根据目录索引日期; 风险价值分录; 如果idx==-1{ 条目={date:date}; 根据指令日期; acc.list.pushentry; }否则{ 条目=附件列表[idx]; } 分录【d.国家】=d.成本; 返回acc }, { 名单:[], 格言:[] }.名单 document.querySelector'result'.innerHTML=JSON.stringifynewData
通过使用字典存储指向与给定日期关联的条目索引的指针,可以限制中间集合的创建。带有reduce函数的示例,没有任何for循环

原始变量=[ {国家:'us',日期:'2014-10-29',成本:45.3}, {国家:“非洲”,日期:“2014-10-29”,费用:60.5}, {国家:'南美洲',日期:'2014-10-30',费用:10}, {国家:'us',日期:'2014-10-30',费用:30} ]; var newData=original.reducefunctionacc,d{ var日期=d日期; var idx=根据目录索引日期; 风险价值分录; 如果idx==-1{ 条目={date:date}; 根据指令日期; acc.list.pushentry; }否则{ 条目=附件列表[idx]; } 分录【d.国家】=d.成本; 返回acc }, { 名单:[], 格言:[] }.名单 document.querySelector'result'.innerHTML=JSON.stringifynewData
查看属性。数据来自哪里?在服务器端更改它可能更容易。输出数组是否为每个日期1条记录?是@JaromandaX。新数据中每个日期只能有一条记录。请参阅属性。数据来自何处?在服务器端更改它可能更容易。输出数组是否为每个日期1条记录?是@JaromandaX。在新数据中,每个日期应该只有一条记录。很好的解释@Bob。我可能会结合使用你的答案和Jaramanda的答案。谢谢:我有点想把它转包给客户,因为我已经需要一个单独的表的更“健壮”的原始数据集了。这样我就省去了一个请求。很好的解释@Bob。我可能会结合使用你的答案和Jaramanda的答案。谢谢:我有点想把它转包给客户,因为我已经需要一个单独的表的更“健壮”的原始数据集了。这样我就可以省下一个请求了。