1

i dont know how to improve my following code - it seems a litte bit ugly:

my data is like:

date d1 d2 d3 d4 d5 d6 
110522 5 1 3 5 0 7 
110523 9 2 4 6 5 9 
110524 0 0 0 0 1 0 
110525 0 0 3 0 4 0 
...

I read in data from a text-file with d3.js and want to generate an "complete" array with following structure:

Array [ Array[10], Array[10], Array[10], Array[10], Array[10] ]
// 10 f.e. is the number of data rows in file

var final1=[];
var final2=[];
var final3=[];
var complete=[];

var dsv = d3.dsv(" ", "text/plain");
dsv("/data/file.txt", function(error, data) {
  data.forEach(function(d) {
    final1.push({x: d.date, y: d.d1});
    final2.push({x: d.date, y: d.d2});
    final3.push({x: d.date, y: d.d3});
    ...
    complete.push(final1);
    complete.push(final2);
    complete.push(final3);
    ...
 });

That code works! But it's very laborious. How can i combine the arrays in an overall array, without the detour of generating a lots of help arrays (final1, final2, ...)?

So end up in an array as follows:

var complete=   [
[{'x':110522,'y':5},{'x':110523,'y':9},{'x':110524,'y':0}, ...],
[{'x':110522,'y':1},{'x':110523,'y':2},{'x':110524,'y':0}, ...],
...
];

2 Answers 2

1

Use a for...in loop to iterate over each of the properties dynamically instead of explicitly handling each one.

var data = [
  { date: 110522, d1: 5, d2: 1, d3: 3, d4: 5, d5: 0, d6: 7 },
  { date: 110523, d1: 9, d2: 2, d3: 4, d4: 6, d5: 5, d6: 9 },
  { date: 110524, d1: 0, d2: 0, d3: 0, d4: 0, d5: 1, d6: 0 },
  { date: 110525, d1: 0, d2: 0, d3: 3, d4: 0, d5: 4, d6: 0 }
];

var results = [];

data.forEach(function (d) {
  var prop;
  var resultIndex = 0;
  
  for (prop in d) {
    if (d.hasOwnProperty(prop) && prop !== 'date') {
      if (!results[resultIndex]) {
        results[resultIndex] = [];
      }
      
      results[resultIndex].push({
        'x': d.date,
        'y': d[prop]
      });
      
      resultIndex++;
    }
  }
});

//Output for demonstration purposes
var element = document.createElement('pre');
element.innerHTML = JSON.stringify(results, null, 4);
document.body.appendChild(element);

Sign up to request clarification or add additional context in comments.

8 Comments

Rather than for..in which requires a hasOwnProperty test (kudos for including it), consider using Object.keys(d).forEach(...). This seems like a candidate for reduce.
@RobG Very true, keys would be cleaner. I think I've just written the for...in/hasOwnProperty pattern (especially in the days of supporting IE < 9) so many times that I default to that.
'y': d[prop] - the y value isn't catch with this method.
@user3265764 What do you mean by that? If you click "Run code snippet" in the answer you can see it working. Is your data object in a different format than what I show?
shortly before this statement, a console.log(d[prop]) shows the correct values. but after filling the results array, y is 'undefined' or ""?
|
0

Your code could be more like:

var complete = [[],[],[]];
var dsv = d3.dsv(' ', 'text/plain');
dsv('/data/file.txt', function(error, data){
  for(var i=0,l=data.length; i<l; i++){
    var d = data[i];
    for(var n=0,q=complete.length; n<q; n++){
      complete[n].push({x:d.date, y:d['d'+(n+1)]});
    }
  }
});

2 Comments

does this only work for a fixed "complete"-array length?
No, as you can see the inner loop is based on complete.length.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.