user8978916
user8978916

Reputation: 31

Custom sorting using Typescript/ javascript

I have the following data:

Data = [
  { "rock": "granite", "youngerThan": "schist"},
  { "rock": "basalt", "youngerThan": null},
  { "rock": "Picrite", "youngerThan": "granite"},
  { "rock": "schist", "youngerThan": "basalt"}
]

etc and I would like to get a sorted array for rock based on attribute youngerThan. Note that youngerThan can be undefined which means this rock is the oldest (at the bottom).

Thus what I want to obtain is the following list: (oldest to youngest)

basalt, schist, granite, picrite

youngest to oldest

picrite,granite, schist, basalt

Upvotes: 3

Views: 10769

Answers (3)

Nina Scholz
Nina Scholz

Reputation: 386624

At least you need to sort the data by the given relation with a tree and then get a sorted result by traversing the tree.

var data = [{ rock: "granite", youngerThan: "schist" }, { rock: "basalt", youngerThan: null }, { rock: "Picrite", youngerThan: "granite" }, { rock: "schist", youngerThan: "basalt" }],
    tree = function (data, root) {
        var r = [], o = {};
        data.forEach(function (a) {
            o[a.rock] = { data: a, children: o[a.rock] && o[a.rock].children };
            if (a.youngerThan === root) {
                r.push(o[a.rock]);
            } else {
                o[a.youngerThan] = o[a.youngerThan] || {};
                o[a.youngerThan].children = o[a.youngerThan].children || [];
                o[a.youngerThan].children.push(o[a.rock]);
            }
        });
        return r;
    }(data, null),
    sorted = tree.reduce(function traverse(r, a) {
        return r.concat(a.data, (a.children || []).reduce(traverse, []));
    }, [])

console.log(sorted);
console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 0

edkeveked
edkeveked

Reputation: 18381

    // Case sensitivity
    var data = [ { "rock": "granite", "youngerThan": "schist"},{ "rock": "schist", "youngerThan": "basalt"},{ "rock": "basalt" },{ "rock": "granite", "youngerThan": "Picrite"}]

    data.sort((a,b) =>{
        if(!a.youngerThan || a.youngerThan < b.youngerThan){
         return -1
        }else if (!b.youngerThan || a.youngerThan > b.youngerThan){
          return 1
        }
        return 0
    })

    console.log(data);

// Case insensitivity
var data = [ { "rock": "granite", "youngerThan": "schist"},{ "rock": "schist", "youngerThan": "basalt"},{ "rock": "basalt" },{ "rock": "granite", "youngerThan": "Picrite"}]

data.sort((a,b) =>{
    var nameA = a.youngerThan ? a.youngerThan.toUpperCase() : null ; // ignore upper and lowercase
    var nameB = b.youngerThan ? b.youngerThan.toUpperCase() : null ; // ignore upper and lowercase
    if(!nameA || nameA < nameB){
     return -1;
    }else if (!nameB || nameA > nameB){
      return 1;
    }
    return 0;
})

console.log(data);

Upvotes: 2

Kumar Shubham
Kumar Shubham

Reputation: 504

The sort function in javascript can take an optional comparator as an argument to sort in a defined order for complex objects like the one you have. I didn't understand fully what you wanted but something like this can be done. I mean you can modify this custom function here to sort the object according to your own preferences.

More info here

function compare(obj1,obj2){
if(obj1.youngerThan === null)
    return -1;
else
    return 1;
}

var Data = [
{ "rock": "granite", "youngerThan": "schist"},
{ "rock": "schist", "youngerThan": "basalt"},
{ "rock": "basalt", "youngerThan": null},
{ "rock": "granite", "youngerThan": "picrite"}
];

Data.sort(compare);

console.log(Data);
/*
[ { rock: 'basalt', youngerThan: null },
{ rock: 'granite', youngerThan: 'picrite' },
{ rock: 'schist', youngerThan: 'basalt' },
{ rock: 'granite', youngerThan: 'schist' } ]
*/

Upvotes: 0

Related Questions