Restructuring a csv file with d3js
First of all: drop the row function, which is the anonymous function as the second argument of csvParse...

var data = d3.csvParse(csvData, function(d) {
    d.date = d.date;
    d.type = d.type
    return d;
})


... because you are not changing anything! 

So, it can be just:

var data = d3.csvParse(csvData);


Back to your question: 

Indeed, you don't need to reference the array by the indices, which forces you to sort the data array and then to sort the resulting array... that's not only confusing and error-prone, but also very computer-intensive for the browser: sorting big arrays of objects can take quite some time. It's a good idea avoiding sorting, specially because, as we'll see, you don't need it.

There is a way to omit that step, making it automatic. Better than that, you can make the whole thing automatic!

In my proposed solution, you don't even need to set the keys, as you do right now...

var keys = ["E","U"];


You can easily get all the unique type values:

var keys = [...new Set(data.map(function(d) {
    return d.type
}))];


And then, creating your lineData:

var lineData = nestData.map(function(d) {
    var obj = {};
    obj.date = d.key;
    keys.forEach(function(e) {
        obj[e] = d.values.find(function(f) {
            return f.key === e
        }).value
    });
    return obj;
});


The above code will work for any number of different types you have, and since you already have the dates in the chronological order, you don't need any sort.

This, in short, is what the function does:


For each map interaction we create a new object:

var obj = {};

We set the key/value pair for the dates, since there is always a date:

obj.date = d.key;

Then, for each value in the keys array, we find the respective value in the values array:

keys.forEach(function(e) {
    obj[e] = d.values.find(function(f) {
        return f.key === e
    }).value
});

Finally, we return the object:

return obj;



Here is a demo, using only the relevant parts in your code:



var csvData = `date,type
2017-01,E
2017-01,E
2017-01,E
2017-01,U
2017-01,U
2017-02,E
2017-02,E
2017-02,U
2017-02,U
2017-02,U
2017-03,U
2017-03,U
2017-03,E
2017-03,E
2017-03,E
2017-03,E`;

var parseTime = d3.timeParse("%Y-%m");

var data = d3.csvParse(csvData);

var keys = [...new Set(data.map(function(d) {
  return d.type
}))];

var nestData = d3.nest()
  .key(d =&gt; d.date)
  .key(d =&gt; d.type)
  .rollup(leaves =&gt; leaves.length)
  .entries(data);

var lineData = nestData.map(function(d) {
  var obj = {};
  obj.date = d.key;
  keys.forEach(function(e) {
    obj[e] = d.values.find(function(f) {
      return f.key === e
    }).value
  });
  return obj;
});

lineData.forEach(function(d) {
  d.date = parseTime(d.date);
})

console.log("Nested: ", nestData)

console.log("Mapped: ", lineData)
&lt;script src="https://d3js.org/d3.v4.min.js"&gt;&lt;/script&gt;
&lt;svg&gt;&lt;/svg&gt;




Now, using this code, you can automatically create the adequate lineData array regardless the number and the order of the type properties in your data array.