1

I'm trying to write a helper function in JavaScript that takes an unsorted array of objects and an array of fields and sorts the array in place based on the given fields. Here's what I have so far:

const sortByFieldsInPlace = (arr, fieldNames) => {
  arr.sort((a, b) => {
    for (const field of fieldNames) {
      if (a[field] > b[field]) return 1;
      if (a[field] < b[field]) return -1;
    }
  });
};

It seems to work so far:

const arr1 = [
  { name: 'A', code: 'D' },
  { name: 'B', code: 'A' },
  { name: 'A', code: 'Z' },
  { name: 'A', code: 'A' },
  { name: 'B', code: 'D' },
  { name: 'B', code: 'B' },
  { name: 'B', code: 'B' }
];
sortByFieldsInPlace(arr1, ['name', 'code'])
console.log(arr1)
// [
//   { name: 'A', code: 'A' },
//   { name: 'A', code: 'D' },
//   { name: 'A', code: 'Z' },
//   { name: 'B', code: 'A' },
//   { name: 'B', code: 'B' },
//   { name: 'B', code: 'B' },
//   { name: 'B', code: 'D' }
// ]

const arr2 = [
  { name: 'A', code: 'D' },
  { name: 'B', code: 'A' },
  { name: 'A', code: 'Z' },
  { name: 'A', code: 'A' },
  { name: 'B', code: 'D' },
  { name: 'B', code: 'B', status: 10 },
  { name: 'B', code: 'B', status: 9 }
];
sortByFieldsInPlace(arr2, ['name', 'code', 'status'])
console.log(arr2)
// [
//   { name: 'A', code: 'A' },
//   { name: 'A', code: 'D' },
//   { name: 'A', code: 'Z' },
//   { name: 'B', code: 'A' },
//   { name: 'B', code: 'B', status: 9 },
//   { name: 'B', code: 'B', status: 10 },
//   { name: 'B', code: 'D' }
// ]

Does this look good or does anyone have a better solution?

4
  • Does this answer your question? Sort array of objects by string property value. Do look beyond the accepted answer - this answer solves the multiple-properties question. Commented Jan 8, 2020 at 20:20
  • 1
    String.prototype.localeCompare() - developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Commented Jan 8, 2020 at 20:22
  • what is the problem with the code? Commented Jan 8, 2020 at 20:23
  • Your approach is clean and simple. Unless you're looking for performance gains, it's ideal IMO. You could potentially replace the 4 line sort predicate with the 2 lines: let field = fieldNames.find(field => a[field] !== b[field]); return field ? a[field].localeCompare(b[field]) : 0; But this would only work for string values. Commented Jan 8, 2020 at 20:26

1 Answer 1

1

Your solution seems good to me, I would add a final "return 0" outside of the for loop to cover the situation where the objects being compared are identical. Other than that I think you have it covered.

1
  • 1
    Good call. Also prevents a console log warning saying Expected to return a value at the end of arrow function Commented Jan 10, 2020 at 2:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.