Home > Net >  Sort an array of objects by multiple fields
Sort an array of objects by multiple fields

Time:09-06

I have an array of objects

let objs = [
  { name: 'Mark',
    age: 30,
    id: 3,
  },
  { name: 'Anne',
    age: 20,
    id: 2,
  },
  { name: 'James',
    age: 40,
    id: 4,
  },
  { name: 'Jerry',
    age: 30,
    id: 1,
  },
  { name: 'Lucy',
    age: 30,
    id: 5,
  },
  { name: 'Mark',
    age: 30,
    id: 6,
  },
]

I have for example an array of fields: ['name', 'age']; The count of fields is dynamic. It could be 2, 1, or 3. If it were static, I would use the sort operator | | like this:

objs.sort((a,b)=> (a.age - b.age || a.name.localeCompare(b.name)));

Any ideas?

CodePudding user response:

You may use this multi sort function from https://stackoverflow.com/a/22672370/3807365 - basically you just tell it which fields to sort by and you shall get a sorting method to pass to your Array.sort.

let objs = [{
    name: 'Mark',
    age: 31,
    id: 3,
  },
  {
    name: 'Anne',
    age: 20,
    id: 2,
  },
  {
    name: 'James',
    age: 40,
    id: 4,
  },
  {
    name: 'Jerry',
    age: 30,
    id: 1,
  },
  {
    name: 'Lucy',
    age: 30,
    id: 5,
  },
  {
    name: 'Mark',
    age: 30,
    id: 6,
  },
]


function getSortMethod() {
  var _args = Array.prototype.slice.call(arguments);
  return function(a, b) {
    for (var x in _args) {
      var ax = a[_args[x].substring(1)];
      var bx = b[_args[x].substring(1)];
      var cx;

      ax = typeof ax == "string" ? ax.toLowerCase() : ax / 1;
      bx = typeof bx == "string" ? bx.toLowerCase() : bx / 1;

      if (_args[x].substring(0, 1) == "-") {
        cx = ax;
        ax = bx;
        bx = cx;
      }
      if (ax != bx) {
        return ax < bx ? -1 : 1;
      }
    }
  }
}

objs.sort(getSortMethod(' name', ' age'));
console.log(objs)
.as-console-wrapper {
  max-height: 100% !important;
}

  • Related