1

I have a dictionary-style array object in JavaScript shown below and would like to sort it by a property. How would this be done? I know questions similar to this have been answered but I think my structure is different. Simply running array.sort(compare) is not working for me because I don't have integers for indexes. Thanks!

var myData = {
    "userOne": {
        "firstName": "Felix",

    },
    "userTwo": {
        "firstName": "Bob",

    },
    "userThree": {
        "firstName": "Anna",

    }
}

I would like the above array myData to be sorted by firstName so that the object with Anna appears first, followed by Bob, followed by Felix. Thank you so much!!

felix_xiao
  • 1,550
  • 5
  • 20
  • 27
  • There is no such thing "*dictionary-style array object*" – Amit Jan 11 '16 at 21:07
  • 2
    You can't -- objects don't have order. – josh3736 Jan 11 '16 at 21:08
  • Are you sure `myData` shouldn't be an array? – Hanlet Escaño Jan 11 '16 at 21:10
  • okay, I guess the best thing for me to do is convert my data format. Thanks! – felix_xiao Jan 11 '16 at 21:10
  • You can create an array from the object - and have that array be sorted with each user obj (like so in current format [{ userThree: { firstName: 'Anna' }}] by doing Object.keys(myData).sort((a, b) => myData[a].firstName > myData[b].firstName).map(key => ({ [key]: myData[key] })). But if you're looking to have a sorted object - it's not possible unless you create a new Map (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) and insert each object based on sort order. – Geoffrey Abdallah Jan 11 '16 at 21:16
  • It's impossible to order objects. See http://stackoverflow.com/questions/1069666/sorting-javascript-object-by-property-value though. – fxck Jan 11 '16 at 21:08

3 Answers3

5

You can use ES6 map which is iterable:

var myData = new Map();
myData.set('userOne', {'firstName': 'Felix'});
myData.set('userTwo', {'firstName': 'Bob'});
myData.set('userThree', {'firstName': 'Anna'});

function sortByProp(data, prop) {
  return new Map([...data.entries()].sort((a, b) => a[1][prop] > b[1][prop]));
};

console.log(sortByProp(myData, "firstName"));
Yoni Mor
  • 344
  • 1
  • 2
  • 11
  • Can you explain a little bit what you are doing here? – 1252748 Jan 12 '16 at 02:12
  • 1
    Sure, 1. Create an ES6 map which is similar to Object but is also ordered (and more) : https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map 2. Insert the elements into the map. 3. Use sortByProp function which breaks the map to an array, sorts it by property name and builds a new, sorted map. I believe logging the [...data.entries()] part may help you understand it better. – Yoni Mor Jan 12 '16 at 08:03
2

Unfortunately it is not possible with your data format. We are dealing with JS object here. According to definition:

An object is a member of the type Object. It is an unordered collection of properties each of which contains a primitive value, object, or function. A function stored in a property of an object is called a method.

If you make it array of objects, that might help.

oKonyk
  • 1,448
  • 10
  • 16
2

Here's some code that would solve your underlying problem, by creating an array instead of an object, populated with the inner objects sorted based on the key:

arrayOfSortedObjects = Object.keys(myData).sort(function(a,b) {
    return myData[a].firstName.localeCompare(myData[b].firstName);
}).map(function(k) {
    return myData[k];
});
Byron A
  • 31
  • 3