0

I have a nested object upon which I want to run a sorting using a nested property. The sortDef will be dynamically set and it might have any value like year or director.name etc.

const mov = [
    {
        "id": "006",
        "name": "Schindler's List",
        "year": 1993,
        "director": {
            "name": "Steven Spielberg",
            "DOB": "01/28/1946"
        },
        "type": 1
    },
    {
        "id": "001",
        "name": "The Shawshank Redemption",
        "year": 1994,
        "director": {
            "name": "Frank Darabont",
            "DOB": "01/28/1959"
        },
        "type": 1
    }
];

const sortDef = {
  fieldName: 'director.name',
  sortingOrder: 'desc'
};

mov.sort((a, b) => (a[sortDef.fieldName].toLocaleLowerCase() > b[sortDef.fieldName].toLocaleLowerCase()) ? 1 : -1)

The sorting works when the sortDef fieldName is like year or name but it fails if it is director.name.

Arkamit
  • 5
  • 2
  • Side note: Your `sort` callback's return is incorrect. It should return `0` when the two elements match, but currently it returns `-1` in that case. – T.J. Crowder May 12 '23 at 08:27

1 Answers1

0

With a method that can read a nested property:

const getValue = (obj,prop) => {
    var parts = prop.split(".");
    return parts.reduce( (a,v) => a[v], obj);
}

You just use that:

const mov = [
    {
        "id": "006",
        "name": "Schindler's List",
        "year": 1993,
        "director": {
            "name": "Steven Spielberg",
            "DOB": "01/28/1946"
        },
        "type": 1
    },
    {
        "id": "001",
        "name": "The Shawshank Redemption",
        "year": 1994,
        "director": {
            "name": "Frank Darabont",
            "DOB": "01/28/1959"
        },
        "type": 1
    }
];

const sortDef = {
  fieldName: 'director.name',
  sortingOrder: 'desc'
};

const getValue = (obj,prop) => {
    var parts = prop.split(".");
    return parts.reduce( (a,v) => a[v], obj);
}


mov.sort((a, b) => (getValue(a,sortDef.fieldName).toLocaleLowerCase() > getValue(b,sortDef.fieldName).toLocaleLowerCase()) ? 1 : -1)

console.log(mov)
Jamiec
  • 133,658
  • 13
  • 134
  • 193