JS: сортировка массива по нескольким полям не работает - PullRequest
1 голос
/ 10 июля 2019

Я хочу создать метод, который сортирует элементы в следующем порядке:

  1. Первым в списке должны быть элементы, которые являются «активными» (для поля isActive установлено значение true). Если оба сравниваемых элемента активны, то сортируются по алфавиту.

  2. Следующими элементами в списке являются те элементы, которым для полей (createSheet и centralBox) присвоено значение true. Если для обоих сравниваемых элементов эти поля имеют значение true, то сортируются по алфавиту.

  3. Следующими элементами в списке являются элементы, для которых только поле centralBox установлено в значение true. Как и в любом другом случае, когда оба элемента имеют эти поля, установленные на true, сортировка производится в алфавитном порядке.

  4. Следующими элементами в списке являются элементы, для которых только для поля createSheet установлено значение true. И так же, как и выше ...

  5. Последняя сортировка в иерархии - сортировка по алфавиту

Это то, что я сделал, и оно не работает (имя - строка, другие поля - логические):

    sortingSelectList = (firstElement, secondElement) => {
    const elementToCompare = {
        name: firstElement.label.toLowerCase(),
        isActive: this.state.activeSystems.ids.includes(firstElement.label),
        createSheet: this.state.systems.entities[firstElement.label].createSheet,
        centralBox: this.state.systems.entities[firstElement.label].centralBox
    };
    const comparingElement = {
        name: secondElement.label.toLowerCase(),
        isActive: this.state.activeSystems.ids.includes(secondElement.label),
        createSheet: this.state.systems.entities[secondElement.label].createSheet,
        centralBox: this.state.systems.entities[secondElement.label].centralBox
    };

    if (elementToCompare.isActive < comparingElement.isActive) { return -1; }
    if (elementToCompare.isActive > comparingElement.isActive) { return 1; }

    if (elementToCompare.centralBox && elementToCompare.createSheet < comparingElement.centralBox && comparingElement.createSheet) { return -1; }
    if (elementToCompare.centralBox && elementToCompare.createSheet > comparingElement.centralBox && comparingElement.createSheet) { return 1; }

    if (elementToCompare.centralBox < comparingElement.centralBox) { return -1; }
    if (elementToCompare.centralBox > comparingElement.centralBox) { return 1; }

    if (elementToCompare.createSheet < comparingElement.createSheet) { return -1; }
    if (elementToCompare.createSheet > comparingElement.createSheet) { return 1; }

    if (elementToCompare.name < comparingElement.name) { return -1; }
    if (elementToCompare.name > comparingElement.name) { return 1; }

    return 0;
}

Может кто-нибудь мне помочь?

Пример:

Object 1: { name: B,
        isActive: true,
        createSheet: false,
        centralBox: false }
Object 2: { name: A,
        isActive: true,
        createSheet: false,
        centralBox: false }         
Object 3: { name: B,
        isActive: false,
        createSheet: false,
        centralBox: false }
Object 4: { name: B,
        isActive: false,
        createSheet: false,
        centralBox: true }
Object 5: { name: B,
        isActive: false,
        createSheet: true,
        centralBox: false }
Object 6: { name: B,
        isActive: false,
        createSheet: true,
        centralBox: true }

Ожидаемый порядок: Объект2 -> Объект1 -> Объект6 -> Объект4 -> Объект5 -> Объект3

Ответы [ 4 ]

1 голос
/ 10 июля 2019

Одним из подходов может быть кодирование и взвешивание объектов в зависимости от вашего состояния. Посмотрите на этот код:

var obj = [
{ name: "B",
  isActive: true,
  createSheet: false,
  centralBox: false },
{ name: "A",
  isActive: true,
  createSheet: false,
  centralBox: false },
{ name: "B",
  isActive: false,
  createSheet: false,
  centralBox: false },
{ name: "B",
  isActive: false,
  createSheet: false,
  centralBox: true },
{ name: "B",
  isActive: false,
  createSheet: true,
  centralBox: false },
{ name: "B",
  isActive: false,
  createSheet: true,
  centralBox: true }
]

for (const o of obj){
  let score = o.isActive === true ? 0 : 50
  score += o.centralBox === true ? 0 : 20
  score += o.createSheet === true ? 0 : 10
  score += o.name.charCodeAt(0)
  o.score = score
}
obj.sort((a, b) => a.score - b.score)
console.log(obj)
0 голосов
/ 10 июля 2019

Вам нужен отдельный объект для хранения требуемого порядка сортировки. В прошлом я использовал следующий код, не свой собственный, но не могу вспомнить, где я его получил, поэтому не могу отдать должное.

Положительное направление обозначает сортировку по возрастанию, а отрицательное - наоборот

let sortBy = [{
  prop:'isActive',
  direction: 1
},{
  prop:'createSheet',
  direction: 1
},
{
  prop:'centralBox',
  direction: 1
},
{
  prop:'name',
  direction:1
}];

Затем вам нужно перебрать каждое из указанных выше свойств, применив каждое из них к массиву:

array.sort(function(a,b){
  let i = 0, result = 0;
  while(i < sortBy.length && result === 0) {
    result = sortBy[i].direction*(a[ sortBy[i].prop ].toString() < b[ sortBy[i].prop ].toString() ? -1 : (a[ sortBy[i].prop ].toString() > b[ sortBy[i].prop ].toString() ? 1 : 0));
    i++;
  }
  return result;
})

Преобразование ToString делает код более гибким, поэтому его можно применять в самых разных ситуациях сортировки.

Мы также умножаем на нужное вам направление.

Применение этого к вашему массиву дает:

enter image description here

0 голосов
/ 10 июля 2019

Сравнения имеют более высокий приоритет, чем &&, поэтому попробуйте изменить

(elementToCompare.centralBox && elementToCompare.createSheet < comparingElement.centralBox && comparingElement.createSheet) с

((elementToCompare.centralBox && elementToCompare.createSheet) < (comparingElement.centralBox && comparingElement.createSheet))

т.е. оберните то, что вы хотите сравнить в скобках.

0 голосов
/ 10 июля 2019

У вас много разных условий.Соу для каждого состояния магазина отфильтрованы результаты.Проверьте фильтр функцию.В конце объедините все массивы в один массив.Проверьте функцию concat .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...