NewUser123
NewUser123

Reputation: 99

sort array by 2 dynamic keys

I have an array like this. I need to write a function to pass in any two fields and have it sorted. example sort('company_id', 'title') should first sort by company_id and then title. How to write a generic function for it

This is the array and my logic:

 [ {
    id: 11861,
    deadline: '01/13/2020',
    status: 'printed',
    buyer_name: 'Dion Murray PhD'
  },
  {
    id: 11848,
    deadline: '12/14/2019',
    status: 'published',
    buyer_name: 'Dion Murray PhD'
  },
  {
    id: 11849,
    deadline: '12/14/2019',
    status: 'published',
    buyer_name: 'Dion Murray PhD'
  },
  {
    id: 11857,
    deadline: '12/22/2019',
    status: 'new',
    buyer_name: 'Dion Murray PhD'
  }

]


sort ( dataToSort, sortField1 , sortField2) {
       rawData.dataToSort( (a, b) => (a[sortField1] > b[sortField1]) ? 1 : ((a[sortField2] > b[sortField2) ? 1 : -1)} ```


TIA.

Upvotes: 0

Views: 194

Answers (4)

Nina Scholz
Nina Scholz

Reputation: 386654

You could take a comparison which works for numbers as well as for strings

a > b || -(a < b)

and get the wanted properties and chain the conditions.

sortBy = (key1, key2) => (a, b) =>
     a[key1] > b[key1] || -(a[key1] < b[key1]) || a[key2] > b[key2] || -(a[key2] < b[key2])

usage:

array.sort(sortBy('company_id', 'title'));

for using an arbitrary count of keys, you could take the parameters as array and iterate the array until the callback gets a value not equal zero.

const
    sortBy = (...keys) => (a, b) => {
        var r = 0;
        keys.some(k => r = a[k] > b[k] || -(a[k] < b[k]));
        return r;
    };

usage:

array.sort(sortBy('company_id', 'title', 'status'));

Upvotes: 2

Erez Pilosof
Erez Pilosof

Reputation: 81

// generic sort, 'propa, propb desc'

function sort(data, sort) {
    var asort=sort.split(',');
    var psort=[];
    for(var i=0,l=asort.length;i<l;i++) {
        var sprop=asort[i].trim();
        if (!sprop) continue;
        var spropa=sprop.split(' ');
        psort.push({prop:spropa[0],desc:(spropa[1]=='desc')?-1:1});
    }

    var psortl=psort.length;
    data.sort(function(a,b) {
        for(var i=0;i<psortl;i++) {
            var cpsort=psort[i];
            if (a[cpsort.prop]>b[cpsort.prop]) return cpsort.desc;
            if (a[cpsort.prop]<b[cpsort.prop]) return 0-cpsort.desc;
        }
        return 0;
    });
    return data;
}

Upvotes: 1

Martial
Martial

Reputation: 1562

You can also use the module lodash with sortBy

Example :

const _ = require('lodash');

const users = [
  { 'user': 'fred',   'age': 48 },
  { 'user': 'barney', 'age': 36 },
  { 'user': 'fred',   'age': 40 },
  { 'user': 'barney', 'age': 34 }
];

_.sortBy(users, ['user', 'age']);
// => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]]

Upvotes: 1

Toto NaBendo
Toto NaBendo

Reputation: 342

You can try :

obj.sort(function(a, b) {
    return a["company_id"] - b["company_id"] || a["title"] - b["title"];
});

Upvotes: -1

Related Questions