-1

Situation: I have a piece of code like

var DealsByMonth = {};
for (var region in this.DealsByRegion) {
    this.DealsByRegion[region].forEach(function (deal) {
        //  deal.Created is in form like "2015-05-04T08:26:38Z"
        var parts = deal.Created.split('-'),
            monthstr = [parseInt(parts[1]), parseInt(parts[0])].join("/");
        if (DealsByMonth[monthstr] !== undefined) {
            ++DealsByMonth[monthstr]
        } else {
            DealsByMonth[monthstr] = 0;
        }
    });
}
console.log(DealsByMonth); // TEST

 var line_data = {
    labels: [],
    datasets: [
        {
            label: "MSfC Deals - Month by Month",
            fillColor: "rgba(220,220,220,0.2)",
            strokeColor: "rgba(220,220,220,1)",
            pointColor: "rgba(220,220,220,1)",
            pointStrokeColor: "#fff",
            pointHighlightFill: "#fff",
            pointHighlightStroke: "rgba(220,220,220,1)",
            data: []
        }
    ]
 }; 

 for ( var key in DealsByMonth ) 
 {
    line_data.labels.push(key);
    line_data.data.push(DealsByMonth[key]);
 }

where what's being printed is an object like

{1/2015: 6, 2/2015: 14, 3/2015: 15, 4/2015: 24, 5/2015: 33, 6/2015: 16, 7/2015: 14, 8/2015: 22, 9/2015: 29, 10/2014: 41, 11/2014: 9, 11/2015: 14, 12/2014: 1, 12/2015: 32}

What I need to extract from that object is the keys but I need to go through them in order because I'm using them to draw a line graph. Either I need to go through them in order or I need to redo my code so that they're in a data structure that is already in order.

What is the correct way to approach this, in terms of elegance, efficiency, readability, etc.?

Subpar Web Dev
  • 3,210
  • 7
  • 21
  • 35

3 Answers3

1

Off the top of my head, sort the keys, then use the sorted order

Object.keys(DealsByMonth).sort(function(a, b) {
    var sa = a.split('/'); // index 0 = month, 1 = year
    var sb = b.split('/');
    var index = (sa[1] == sb[1]) ? 0 : 1; // if year is same, compare months
    return parseFloat(sa[index]) - parseFloat(sb[index]);
}).forEach(function(key) {
    line_data.labels.push(key);
    line_data.data.push(DealsByMonth[key]);
});
Jaromanda X
  • 53,868
  • 5
  • 73
  • 87
0

Similar to this answer,

multiSort(DealsByMonth);

function multiSort(object) {
  var months = Object.keys(object);
  months.sort(function(a, b) {
    var m1 = a.split('/')[0];
    var m2 = b.split('/')[0];
    var y1 = a.split('/')[1];
    var y2 = b.split('/')[1];

    if (y1 < y2) return -1;
    if (y1 > y2) return 1;
    if (parseInt(m1) < parseInt(m2)) return -1;
    if (parseInt(m1) > parseInt(m2)) return 1;
    return 0;
  });
  var reorderedObj = {};
  for (var i = 0; i < months.length; i++) {
    reorderedObj[months[i]] = object[months[i]];
  }
  return reorderedObj;
}
Community
  • 1
  • 1
Bennett Adams
  • 1,808
  • 14
  • 17
0

If you want the data to be ordered properly in the object, you should keep the keys in a way that it compares correctly (the way you want it). When comparing two dates the first thing you should compare is their years, then month and then days. In your code you have kept month before the year e.g : "1/2015", that's incorrect if you wanted it ordered properly because based on this format "4/2014" comes after "1/2015", which is not you want.

So I suggest you that you keep year in the front and month after it, change:

monthstr = [parseInt(parts[1]), parseInt(parts[0])].join("/");

to:

monthstr = [parseInt(parts[0]), parseInt(parts[1])].join("/");
limekin
  • 1,934
  • 1
  • 12
  • 15