JavaScript - Как отсортировать массив объектов по 3 различным типам атрибутов? (String, Integer, Boolean) - PullRequest
0 голосов
/ 31 августа 2018

У меня есть массив объектов:

var a = [
  {"name": "BBB", "no": 2, "size1": [3], "size2": null },
  {"name": "AAA", "no": 5, "size1": null, "size2": [1] },
  {"name": "BBB", "no": 1, "size1": [2], "size2": null },
  {"name": "AAA", "no": 4, "size1": null, "size2": [1] },
  {"name": "BBB", "no": 1, "size1": null, "size2": [1] },
  {"name": "AAA", "no": 5, "size1": [2], "size2": null },
  {"name": "BBB", "no": 2, "size1": null, "size2": [1] },
];

Я хочу отсортировать его следующим образом: Сортировать по name по возрастанию, затем no по возрастанию, а затем по размеру1, если оно не равно нулю.

Сначала я могу отсортировать по name и no, но после этого я не знаю, как отсортировать по size1 или size2. Сначала он должен быть отсортирован по size1, если он не равен нулю. Вот мой код для сортировки

function sortObject(arrayObjects){
    arrayObjects.sort(function(a,b){
        if(a.name=== b.name){
            return (a.no - b.no);
        } else if(a.name > b.name){
            return 1;
        } else if(a.name < b.name){
            return -1;
        }
    });
}

Ожидаемый результат

var a = [
  {"name": "AAA", "no": 4, "size1": null, "size2": [1] },
  {"name": "AAA", "no": 5, "size1": [2], "size2": null },
  {"name": "AAA", "no": 5, "size1": null, "size2": [1] },
  {"name": "BBB", "no": 1, "size1": [2], "size2": null },
  {"name": "BBB", "no": 1, "size1": null, "size2": [1] },
  {"name": "BBB", "no": 2, "size1": [3], "size2": null },
  {"name": "BBB", "no": 2, "size1": null, "size2": [1] },
]

Ответы [ 4 ]

0 голосов
/ 31 августа 2018

Вы можете попробовать что-то вроде этого:

var a = [
  {"name": "AAA", "no": 4, "size1": null, "size2": [1] },
  {"name": "AAA", "no": 5, "size1": [2], "size2": null },
  {"name": "AAA", "no": 5, "size1": null, "size2": [1] },
  {"name": "BBB", "no": 1, "size1": [2], "size2": null },
  {"name": "BBB", "no": 1, "size1": null, "size2": [1] },
  {"name": "BBB", "no": 2, "size1": [3], "size2": null },
  {"name": "BBB", "no": 2, "size1": null, "size2": [1] },
]

a.sort(function(a, b){
  return  a.name.localeCompare(b.name) ||
          a.no - b.no ||
          (b.size1 === null) - (a.size1 === null) ||
          (b.size2 === null) - (a.size2 === null)
});

console.log(a)
0 голосов
/ 31 августа 2018

Вы можете использовать модифицированную версию orderBy из 30-секундного кода (проект / веб-сайт, который я поддерживаю), который также проверяет на null и заказывает соответственно:

var a = [
{"name": "BBB", "no": 2, "size1": [3], "size2": null },
{"name": "AAA", "no": 5, "size1": null, "size2": [1] },
{"name": "BBB", "no": 1, "size1": [2], "size2": null },
{"name": "AAA", "no": 4, "size1": null, "size2": [1] },
{"name": "BBB", "no": 1, "size1": null, "size2": [1] },
{"name": "AAA", "no": 5, "size1": [2], "size2": null },
{"name": "BBB", "no": 2, "size1": null, "size2": [1] },
];

const orderBy = (arr, props, orders) =>
  [...arr].sort((a, b) =>
    props.reduce((acc, prop, i) => {
      if (acc === 0) {
        const [p1, p2] = orders && orders[i] === 'desc' ? [b[prop], a[prop]] : [a[prop], b[prop]];
        acc = p1 === null ? 1 : p2 === null ? -1 : p1 > p2 ? 1 : p1 < p2 ? -1 : 0;
      }
      return acc;
    }, 0)
  );
  
 var aSorted = orderBy(a, ['name', 'no', 'size1', 'size2'], ['asc', 'asc', 'asc', 'asc']);
 
 console.log(aSorted);

Как orderBy работает:

Использует Array.sort(), Array.reduce() в массиве props со значением по умолчанию 0, использует деструктуризацию массива для изменения положения свойств в зависимости от переданного порядка. Если массив orders не передан, по умолчанию сортируется по 'asc'.

0 голосов
/ 31 августа 2018

Вы можете сделать это

  1. Для сравнения строк String.prototype.localeCompare()
  2. Для вычитания числа / длины массива

DEMO

const arr = [
{"name": "BBB", "no": 2, "size1": [3], "size2": null },
{"name": "AAA", "no": 5, "size1": null, "size2": [1] },
{"name": "BBB", "no": 1, "size1": [2], "size2": null },
{"name": "AAA", "no": 4, "size1": null, "size2": [1] },
{"name": "BBB", "no": 1, "size1": null, "size2": [1] },
{"name": "AAA", "no": 5, "size1": [2], "size2": null },
{"name": "BBB", "no": 2, "size1": null, "size2": [1] },
];

arr.sort((a, b) => {
  let check = a.name.localeCompare(b.name);
  if (check == 0) {
    check = a.no - b.no;
    if (check == 0) {
      check = (b.size1 || []).length - (a.size1 || []).length;
    }
  }
  return check;
});

console.log(arr)
.as-console-wrapper {max-height: 100% !important;top: 0;}
0 голосов
/ 31 августа 2018

Вы должны сравнить no в своем первом if:

function sortObject(arrayObjects){
    arrayObjects.sort(function(a,b){
        if (a.name=== b.name) {
            if (a.no === b.no) {
                // Determines which size to use for comparison
                const aSize = a.size1 || a.size2;
                const bSize = b.size1 || b.size2;

                return (aSize[0] - bSize[0]);
            }
            return (a.no - b.no);
        } else if (a.name > b.name) {
            return 1;
        } else if (a.name < b.name) {
            return -1;
        }
    });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...