2014-10-31 79 views
2

我对JavaScript很新颖。目前我的数据是CSV格式:以Javascript重新排列数据

place, time, value 
a, 2009, 25 
b, 2009, 35 
c, 2009, 14 
a, 2010, 42 
b, 2010, 13 
etc. 

我想在格式[{'place': 'a', 'data':[{'t': '2009', 'v': '25'}, {'t': '2010' etc.安排数据,所以我可以做一些线图中D3

我目前使用下面的代码。不过,我觉得这样做效率不高,因为如果我有相当数量的数据(40年以上的30个地方),JavaScript将遍历所有数据30次。我还有其他方法可以解决这个问题吗?

var instlist = [{'place': 'a', 'data':[]}, {'place':'b', 'data':[]}]; 
var data = instlist; 

for (var i = 0; i < placelist.length; i++){ 
for (var j = 0; j < rawData.length; j++){ 
    if (rawData[j]['place'] == instlist[i]['place']) { 
     data[i]['data'].push({'t': rawData[j]['t'],'v': rawData[j]['v']}) 
     } 
    } 
} 

谢谢。欢呼声

+0

嗨。你的'rawData'数组是什么样的?是这样的:'rawData = [{'place':'a | b | ...','data':{'t':...,'v':...}},{'放置':'a | b | ...','data':{'t':...,'v':...}},...]' – 2014-10-31 16:38:50

+0

这实际上看起来不那么糟糕。有一件事,我会在循环前将'placelist.length'和'rawData.length'存储在变量中,否则它们将在每次迭代时重新计算。 – 2014-10-31 16:41:23

+0

如果你的数据总是这样,你可以使用一些库,如https://lodash.com/来解析和存储帮助程序。如果你来自MVC PHP或有LINQ积压,一切都会很容易理解。 @ Andy的回答很好。 – 2014-10-31 16:47:42

回答

3

由于它是一个D3问题,D3-溶液简洁。如果您有单独的CSV文件,则可以使用d3.csv来加载它。第一

var csvString = [ 
 
    'place,time,value', 
 
    'a,2009,25', 
 
    'b,2009,35', 
 
    'c,2009,14', 
 
    'a,2010,42', 
 
    'b,2010,13' 
 
].join('\n'); 
 

 
var rows = d3.csv.parse(csvString); 
 
var data = d3.nest() 
 
    .key(function(d) 
 
    { 
 
    return d.place; 
 
    }) 
 
    .entries(rows); 
 

 
console.log(data);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

+0

出于兴趣,这是否提供了OP想要的输出:'[{'place':'a','data':[{'t':'2009','v':'25'}'或don你认为这是必要的吗? – Andy 2014-10-31 17:10:51

+0

@安迪首先,他告诉他是初学者。其次,这是一个D3问题。所以我确定他想把''''键重命名为'''''键,因为它是图书馆做它的方式。并测量代码维护成本,我会做同样的事情。 – saaj 2014-10-31 17:18:19

+0

@saaj感谢您参考d3。我认为这正是我想要的,但是我无法将它与'd3.csv'结合起来。我使用var行; d3.csv('testcsv2.csv',function(error,input)rows = input;})'然后继续'var data = d3.nest()',它告诉我该数组未定义。有什么建议么? – As3adTintin 2014-10-31 18:36:23

0

这只是使用一个循环。它沿着回车符将CSV分成strArr并创建一个新的输出数组。然后它从元素1遍历strArr到数组的长度(即从标签之后),通过逗号将剩余的元素拆分成一个新数组,并将每个新对象推送到输出数组。

var strArr = str.split('\n'); 
var out = []; 
for (var i = 1, l = strArr.length; i < l; i++) { 
    var elems = strArr[i].split(','); 
    out.push({ 
    place: elems[0], 
    data: [{ t: elems[1], v: elems[2] }] 
    }); 
} 

DEMO

0

第一件事,我会存储在变量placelist.lengthrawData.length循环之前,或在每次迭代它们将被重新计算:

var instlist = [{'place': 'a', 'data':[]}, {'place':'b', 'data':[]}]; 
var data = instlist; 

var placelistLen = placelist.length; 
var rawDataLen = rawData.length; 

for (var i = 0; i < placelistLen; i++){ 
for (var j = 0; j < rawDataLen; j++){ 
    if (rawData[j]['place'] == instlist[i]['place']) { 
     data[i]['data'].push({'t': rawData[j]['t'],'v': rawData[j]['v']}) 
     } 
    } 
} 

其次,如果你愿意稍微改变输出结构,你可以大大减少迭代次数。

var instlist = { 'a': [], 'b': [] }; 
var data = instlist; 
var rawDataLen = rawData.length; 

for (var i = 0; i < rawDataLen; i++) { 
    data[rawData[i]['place']].push({'t': rawData[i]['t'],'v': rawData[i]['v']}) 
} 

我不是专家,所以我不知道这会多快,但它确实删除了条件并减少了迭代次数。另一方面,不同的数据结构可能不适合你的目的。