keldar
keldar

Reputation: 6242

Sorting JavaScript object arrays based on arbitrary lenght of properties

I have a JavaScript sort array function which takes a string I provide it, which is the name of the property I want to sort by and it sorts my array by that property name.

Thus:

function sortProp(myArr, prop) {
    return myArray.sort(function (a, b) {
        return a[prop] < b[prop];
    }
}

What I would like, is for this sort function to continue taking this string but can read it as an arbitrary length of properties to sort by; this is probably explained easier in an example below:

I have a JavaScript array of objects which takes the following structure (this is just an example to show multi-level nesting I have):

{
    {
        "Name" : "John Smith"
        "Address" : {
            "Line 1" : "123 Some Street"
            "Line 2" : "Some Neighbourhood"
            "Town" : "Some Town"
            "PostCode" : "ST1 1ST"
            "Contract" : {
                "Name" : "CON1"
                "Hours" : 24
            }
        }
    },

    {
        "Name" : "Mary Jones"
        "Address" : {
            "Line 1" : "321 Some Other Street"
            "Line 2" : "Some Other Neighbourhood"
            "Town" : "Some Other Town"
            "PostCode" : "SO1 1OS"
            "Contract" : {
                "Name" : "CON2"
                "Hours" : 48
            }
        }
    }
}

On my user interface, I have a dropdown which certain values to the properties in this array; thus I might have sort by:

However, at the moment my sort function has to decode how many '.' there are by splitting at it, then I can sort based on arr[prop1] or arr[prop1][prop2] or arr[prop1][prop2][prop3] which means I have to explicitly state the array depth I'm referring to.

Ideally what I'd like, is to provide it that string, then the function works out the level of nesting it needs - but I can't figure out how to do that since I'm not sure of any other way other than explicitly stating the array indexes.

Is there something that can be achieves, so I can pass my sort function some of the following, and it works out the nesting required without me having to write hardcode the array depths, e.g.:

sort(myArray, "Name")
sort(myArray, "Address.PostCode")
sort(myArray, "Address.Contract.Hours")
sort(myArray, "Address.Contract.ExampleProp1")
sort(myArray, "Address.Contract.ExampleProp1.ExampleProp2.ExampleProp3")

Thus, so I can provide it an argument of any sized property length and it figures that out.

Hope that makes sense :) thanks.

Edit 1: changed the title

Edit 2: corrected my first

Upvotes: 3

Views: 363

Answers (1)

georg
georg

Reputation: 214949

Use cmp from Grouped sorting on a JS array and ref from Convert string in dot notation to get the object reference ;)

prop = "Address.Contract.ExampleProp1"
ary.sort(function(a, b) {
    return cmp(ref(a, prop), ref(b, prop))
})

Upvotes: 2

Related Questions