Question

I have this data set in object, keys are strings

 { '17': '17-17:30',
   '20': '20:00-21',
   '21': '21-22',
   '22': '22-23',
    '23': '23-24',
   '01': '1-2',
   '02': '2-3',
   '03': '3-4',
   '04': '4-5',
   '05': '5-6',
   '06': '6-7',
  '07': '7-7:30',
  '08': '08:50-9' }

I want to arrange them numerically so that 01 comes first and 23 comes last.

Here's the code I'm using:

    var sort_object = function(map) {
    var keys = _.sortBy(_.keys(map), function(a) { return Number(a); });
    var newmap = {};
    _.each(keys, function(k) {
    newmap[k] = map[k];
     });
     return newmap;
    }

it still returns 17 in the beginning. Where did I go wrong?

Was it helpful?

Solution

As Blender pointed out, objects are not ordered. You need to use an array. There are several ways you could set up this array, and once you have the data in an array it's very easy to sort it.

Here are a couple of examples. First, let's try making this an array of arrays. The outer array is the list of elements, and each element of this array is itself an array of two elements, your key and your value.

So paste this code into your favorite JavaScript console, such as the one in Chrome:

var data = [
    [ '17', '17-17:30' ],
    [ '20', '20:00-21' ],
    [ '21', '21-22' ],
    [ '22', '22-23' ],
    [ '23', '23-24' ],
    [ '01', '1-2' ],
    [ '02', '2-3' ],
    [ '03', '3-4' ],
    [ '04', '4-5' ],
    [ '05', '5-6' ],
    [ '06', '6-7' ],
    [ '07', '7-7:30' ],
    [ '08', '08:50-9' ]
];

var result = data.slice().sort( function( a, b ) {
    return +a[0] - +b[0];
});

JSON.stringify( result, null, 4 );

It will log:

[
    [
        "01",
        "1-2"
    ],
    [
        "02",
        "2-3"
    ],
    [
        "03",
        "3-4"
    ],
    [
        "04",
        "4-5"
    ],
    [
        "05",
        "5-6"
    ],
    [
        "06",
        "6-7"
    ],
    [
        "07",
        "7-7:30"
    ],
    [
        "08",
        "08:50-9"
    ],
    [
        "17",
        "17-17:30"
    ],
    [
        "20",
        "20:00-21"
    ],
    [
        "21",
        "21-22"
    ],
    [
        "22",
        "22-23"
    ],
    [
        "23",
        "23-24"
    ]

Or, instead of an array of arrays, you can use an array of objects. This is often more convenient to work with. Paste this code into the JavaScript console:

var data = [
    { key: '17', value: '17-17:30' },
    { key: '20', value: '20:00-21' },
    { key: '21', value: '21-22' },
    { key: '22', value: '22-23' },
    { key: '23', value: '23-24' },
    { key: '01', value: '1-2' },
    { key: '02', value: '2-3' },
    { key: '03', value: '3-4' },
    { key: '04', value: '4-5' },
    { key: '05', value: '5-6' },
    { key: '06', value: '6-7' },
    { key: '07', value: '7-7:30' },
    { key: '08', value: '08:50-9'}
];

var result = data.slice().sort( function( a, b ) {
    return +a.key - +b.key;
});

JSON.stringify( result, null, 4 );

It will log:

[
    {
        "key": "01",
        "value": "1-2"
    },
    {
        "key": "02",
        "value": "2-3"
    },
    {
        "key": "03",
        "value": "3-4"
    },
    {
        "key": "04",
        "value": "4-5"
    },
    {
        "key": "05",
        "value": "5-6"
    },
    {
        "key": "06",
        "value": "6-7"
    },
    {
        "key": "07",
        "value": "7-7:30"
    },
    {
        "key": "08",
        "value": "08:50-9"
    },
    {
        "key": "17",
        "value": "17-17:30"
    },
    {
        "key": "20",
        "value": "20:00-21"
    },
    {
        "key": "21",
        "value": "21-22"
    },
    {
        "key": "22",
        "value": "22-23"
    },
    {
        "key": "23",
        "value": "23-24"
    }
]

Either way, as you can see, once you have your data in a suitable format (i.e. the data as a whole needs to be an array), then it becomes very simple to sort it.

Let's look at that sort function in more detail (using the second example):

var result = data.slice().sort( function( a, b ) {
    return +a.key - +b.key;
});

In this code a.key gets the value for the key property of one of the array elements. The + in front of that converts the string to a number - much like using the Number function but a simpler way to do it. Similarly for +b.key. And then subtracting those two numbers gives the correct sort function return: a positive, negative, or zero value depending on whether a.key or b.key is the greater of the two or if they're equal.

The first example works similarly, just using +a[0] - +b[0] instead of +a.key - +b.key.

The .slice() call in each example makes a copy of the array. You could omit that if you want to sort the original array.

OTHER TIPS

The only way to imply order would be to use an array. How about an array of key/value objects, eg

return Object.keys(map).sort().map(function(k) {
    return {key: k, value: foo[k]}
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top