2

I want to sort some Object look likes this

data = {
        "imH3i4igFNxM3GL": {
            "name": "Nacky",
            "age": 12
        },
        "vuzPuZUmyT8Z5nE": {
            "name": "Emmy",
            "age": 20
        },
        "OkIPDY1nGjxlq3W": {
            "name": "Nat",
            "age": 20
        }
}

I want to sort it by "name". I tried to use Lodash for this problem.

_.sortBy(data, [function(o) { return o.name; }]);

but, it return me an array of objects without the keys

[
    {
      "name": "Emmy",
      "age": 20
    },
    {
      "name": "Nacky",
      "age": 12
    },
    {
      "name": "Nat",
      "age": 20
    }
]

I want it return me sorted object with key like the same

{
    "vuzPuZUmyT8Z5nE": {
        "name": "Emmy",
        "age": 20
    },
    "imH3i4igFNxM3GL": {
        "name": "Nacky",
        "age": 12
    },
    "OkIPDY1nGjxlq3W": {
        "name": "Nat",
        "age": 20
    }
}

what should I do? thanks

NutAnek
  • 21
  • 1
  • 3
  • You're not sorting an array; you're trying to sort an object. This is generally a bad idea, since iterating over the object is not guaranteed to output the keys in the order you want [see this comment on a similar question](http://stackoverflow.com/questions/1069666/sorting-javascript-object-by-property-value#comment67886877_1069666) – Heretic Monkey May 08 '17 at 16:42
  • Well, `_.sortBy` accepts an object but will return an array, as per the doc. As Mike says, you cannot get an object with "sorted" keys. – Hugues M. May 08 '17 at 16:45

2 Answers2

3

Objects in JS can't be sorted, and the order of the properties is not reliable, ie it depends on browsers' implementations. That's why _.sortBy() is converting your object into a sorted array.

I can think of 2 options to work with that.

Add the key to the objects in the array

If you just need an ordered array with the keys in the objects, so you can render a list.

var data = {
        "imH3i4igFNxM3GL": {
            "name": "Nacky",
            "age": 12
        },
        "vuzPuZUmyT8Z5nE": {
            "name": "Emmy",
            "age": 20
        },
        "OkIPDY1nGjxlq3W": {
            "name": "Nat",
            "age": 20
        }
};

var result = _(data)
  .map(function(v, k) { // insert the key into the object
    return _.merge({}, v, { key: k });
  })
  .sortBy('name') // sort by name
  .value();
  
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

Create an order array

Create an array of ordered keys, and use them when you wish to render the objects in order.

var data = {
        "imH3i4igFNxM3GL": {
            "name": "Nacky",
            "age": 12
        },
        "vuzPuZUmyT8Z5nE": {
            "name": "Emmy",
            "age": 20
        },
        "OkIPDY1nGjxlq3W": {
            "name": "Nat",
            "age": 20
        }
};

var orderArray = _(data)
  .keys() // create an array of keys
  .sortBy(function(key) { // sort the array using the original names
    return data[key].name;
  }) // sort by name
  .value();

console.log('The order array', orderArray);

console.log(orderArray.map(function(k) {
  return data[k];
}));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
0

I use something like this.

    let data = {
    'g34ghgj3kj': {
        YOUR_KEY: 'g34ghgj3kj',
        'key1': false,
        'key2': false,
    },
    'hh334h664': {
        YOUR_KEY: 'hh334h664',
        'key1': true,
        'key2': false,
    },
    //{...}
};

_.orderBy(data, ['key1', 'key2'], ['desc', 'desc']).reduce((result, value) => {
    result[value.YOUR_KEY] = value;
    return result;
}, {});
Ilya Degtyarenko
  • 1,359
  • 8
  • 16