Transforming data from an array of objects to a nested array of objects I have an array of objects where each object has a datetime key/value pair:

var original = [
  {
    datetime: '2015-07-22 09:00:00'
  },
  {
    datetime: '2015-07-22 11:00:00'
  },
  {
    datetime: '2015-07-23 10:00:00'
  }
]


I need to transform them into a new array with objects where the first key/value pair of each object is the date associated with an array of datetimes from the original array of objects. The second key/value pair is an array of the original objects which have a datetime date that matches the new date.

var new = [
  {
    date: '2015-07-22',
    events: [
      {
        datetime: '2015-07-22 09:00:00'
      },
      {
        datetime: '2015-07-22 11:00:00'
      }
    ]
  },
  {
    date: '2015-07-23',
    events: [
      {
        datetime: '2015-07-23 10:00:00'
      }
    ]
  }
];


Below is my current method of making this transformation happen and it is this method that I am seeking to improve upon. It is clunky. It is convoluted. It is hacky.

I am currently selecting the substring from the first object's datetime as currentDate which only contains the date. Then I'm creating an empty array, new. as well as an object as datum which contains a date key with currentDate as it's value  and an events key with an empty array as its value.

var currentDate = original[0].datetime.substring(0,10); // =&gt; '2015-07-22';
var new = [];
var datum = {
  date: currentDate,
  events: []
};


Then I'm using a forEach function on the original array in the following manner:

original.forEach(function(item){

  //if item's date matches currentDate add it to datum object
  if (item.datetime.substr(0,10) === currentDate){
    datum.events.push(item);
  }

  //if item's date does not match then it is the next date 
  else {

    //add the previous day's datum object to the new array 
    new.push(datum);

    //set new currentDate and set new datum object
    currentDate = item.datetime.substr(0,10);
    datum = {
      date: currentDate,
      events: []
    };

    //push the current item into the new datum array
    datum.events.push(item);
  }
});

//push final day's datum to new array
new.push(datum);


What is a more efficient way to transform this data?
The general idea of your attempt is not so bad.

Its main default is to be not generic enough so you repeat some code. This can be simply avoided using this (already antique) rule: never prepare a container before you know you need it.
So here, instead of immediately creating a first date item, wait for the time you see that it's required.

A fortunate side effect is that it responds to another lack in your code: if original contains a sequence of unsorted events, it will fail. With the new method, all events will be regularly processed.
(look at this fiddle, where I intentionally interweaved dates)

Modified code looks like this:

var original = [
  {
    datetime: '2015-07-22 09:00:00'
  },
  {
    datetime: '2015-07-22 11:00:00'
  },
  {
    datetime: '2015-07-23 10:00:00'
  }
];
var result = [], // (don't like "var new", which is a reserved word!)
    index = [];

for (var i in original) {
  var date = original[i].datetime,
      day = date.substr(0,10),
      j = index.indexOf(day);
  if (j == -1) {
    // first instance for the current day, create it
    result.push({
      date: day,
      event: [],
    });
    // register its index
    index.push(day);
    // get this new index value
    j = index.length - 1;
  }
  // in any case, populate the right day with the current event
  result[j].event.push(date);
}