Упорядочить массив объектов, работающих на число, но не на строку - PullRequest
0 голосов
/ 06 января 2020

Я создал функцию util для сортировки массива объектов в порядке возрастания или убывания, который принимает свойство. Кажется, он отлично работает для сортировки чисел c, но не для свойств строк. Например, ниже, если вы передаете «age» в качестве второго аргумента, он упорядочивается правильно, однако, если вы передаете «job» в качестве второго аргумента, ничего не происходит. Я надеялся, что он будет упорядочен в алфавитном порядке по работе (инженер, маркетинг, продажи). Есть идеи как это исправить / почему это происходит?

const arrayOfObjects = [
  { firstName: 'Joe', job: 'Engineer', age: 22 },
  { firstName: 'Sam', job: 'Sales', age: 30 },
  { firstName: 'Claire', job: 'Engineer', age: 40 },
  { firstName: 'John', job: 'Marketing', age: 29 },
  { firstName: 'Susan', job: 'Engineer', age: 21 },
];

const orderByValue = (array, orderByItem, order) => array.sort((a, b) => {
  if (order === 'descending') {
    return b[orderByItem] - a[orderByItem];
  } else {
    return a[orderByItem] - b[orderByItem];
  }
});

// console.log('order by age:', orderByValue(arrayOfObjects, 'age'));
console.log('order by job:', orderByValue(arrayOfObjects, 'job'));

Ответы [ 2 ]

4 голосов
/ 06 января 2020

Вы можете просто использовать LocaleCompare и использовать опцию Numeri c для обработки чисел

LocaleCompare - это метод String, поэтому для правильной обработки числовых типов вы конвертируйте их, используя .toString(), a[orderByItem] + '' или String(a[orderByItem])

const arrayOfObjects = [
  { firstName: 'Joe', job: 'Engineer', age: 22 },
  { firstName: 'Sam', job: 'Sales', age: 30 },
  { firstName: 'Claire', job: 'Engineer', age: 40 },
  { firstName: 'John', job: 'Marketing', age: 29 },
  { firstName: 'Susan', job: 'Engineer', age: 21 },
];

const orderByProperty = (array, orderByItem, order) => array.sort((a, b) => {
  if (order === 'descending') {
    return b[orderByItem].toString().localeCompare(a[orderByItem].toString(), 'en', {numeric: true});
  } else {
    return a[orderByItem].toString().localeCompare(b[orderByItem].toString(), 'en', {numeric: true});
  }
});

console.log('order by age:', orderByProperty(arrayOfObjects, 'age'));
console.log('order by job:', orderByProperty(arrayOfObjects, 'job'));
.as-console-wrapper {max-height: 100% !important; top: 0;}
1 голос
/ 06 января 2020

Вы можете вернуть функцию в качестве обратного вызова и пропустить для каждого сравнения проверку заказа.

В этом подходе используются просто большие / меньшие операторы, которые также работают со строками.

const arrayOfObjects = [
  { firstName: 'Joe', job: 'Engineer', age: 22 },
  { firstName: 'Sam', job: 'Sales', age: 30 },
  { firstName: 'Claire', job: 'Engineer', age: 40 },
  { firstName: 'John', job: 'Marketing', age: 29 },
  { firstName: 'Susan', job: 'Engineer', age: 21 },
];

const orderByProperty = (array, orderByItem, order) => array.sort(order === 'descending'
    ? (a, b) => b[orderByItem] > a[orderByItem] || -(b[orderByItem] < a[orderByItem])
    : (a, b) => a[orderByItem] > b[orderByItem] || -(a[orderByItem] < b[orderByItem])
);

console.log('order by age:', orderByProperty(arrayOfObjects, 'age'));
console.log('order by job:', orderByProperty(arrayOfObjects, 'job'));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...