Сортировка массива объектов в порядке возрастания и убывания одним щелчком - PullRequest
1 голос
/ 28 июня 2019

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

var arr = [{
  title: "finance",
  book: "book1"
},
{
  title: "nature",
  book: "book2"
},
{
  title: "programming",
  book: "book3"
}]

HTML:

<th><a href="#" ng-click="controller.sortTitle()">TITLE</a></th>

Прямо сейчас я реализовал базовую логику сортировки ниже

JAVASCRIPT (контроллер AngularJS):

self.sortTitle = function () {
    self.arr= self.arr.sort((a, b) => (a.title > b.title) ? 1 : -1);
}

Эта функция JavaScript в настоящее время сортирует ее в порядке возрастания только на основе заголовка.Как мне написать логику, которая сортирует его в любом порядке, то есть click1 должен отсортировать его по возрастанию, а click2 должен повернуть вспять и установить его по убыванию?По сути, при каждом щелчке производится смена сортировки.

Ответы [ 6 ]

1 голос
/ 28 июня 2019

Вы можете создать свойство на self, например isAscending, и по умолчанию установить значение true или false (все, что вы хотите вначале) в зависимости от того, какой порядок сортировки будет выполняться, и переключать isAscending каждый раз, когда выполняется сортировка fn.

self.isAscending = true;

self.sortTitle = function () {
 if(self.isAscending){ 
   self.arr= self.arr.sort((a, b) => (a.title > b.title) ? 1 : -1);
 }else{
   self.arr= self.arr.sort((a, b) => (a.title > b.title) ? -1 : 1);
 }
 self.isAscending = !self.isAscending;
}
0 голосов
/ 28 июня 2019

Возможно, имеет смысл иметь функцию reusable, которую вы можете вызвать для сортировки, которая также принимает direction parameter:

var arr = [{ title: "finance", book: "book1" }, { title: "nature", book: "book2" }, { title: "programming", book: "book3" }]

let sortBy = (arr, p, o=1) => [...arr].sort((a,b) => a[p].localeCompare(b[p]) * o)

console.log(sortBy(arr, 'title'))
console.log(sortBy(arr, 'title', -1))
console.log(sortBy(arr, 'book'))
console.log(sortBy(arr, 'book', -1))

При необходимости вы можете заменить последний параметр на asc/desc.

Кроме того, поскольку вы сравниваете строки, рекомендуется использовать String.localeCompare просто из-за количества поддерживаемых опций, которые почти всегда пригодятся (например, сортировка book10 против book1) )

0 голосов
/ 28 июня 2019

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

self.sortTitle = function () {
    sortArrayAsc = !sortArrayAsc;
    self.arr= self.arr.sort((a, b) => sort(a,b, sortArrayAsc));
}

// ToDo: You can writte this nicer
self.sort = function (a, b, ascending) {
    if(ascending) {
        return a.title > b.title ? 1 : -1;
    } else {
        return a.title > b.title ? -1 : 1;
    }
}

0 голосов
/ 28 июня 2019

Создайте логическую переменную со значением false.В вашей функции sortTitle() создайте условие, которое будет определять, является ли оно истинным или ложным, а затем запускать противоположное, когда оно истинно.

0 голосов
/ 28 июня 2019

Добавьте переменную в вашу функцию и измените условное

self.sortTitle = function (sortOrder) {
    if (sortOrder === 'asc') {
        self.arr= self.arr.sort((a, b) => (a.title > b.title) ? 1 : -1);
    } else { //desc
        self.arr= self.arr.sort((a, b) => (a.title < b.title) ? 1 : -1);
    }
}
0 голосов
/ 28 июня 2019

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

Есть много вариантов, но должно работать что-то простое:

const ascendingComparator = (a, b) => (a.title > b.title) ? 1 : -1;
const descendingComparator = (a, b) => (a.title > b.title) ? -1 : 1;

self.sortTitle = function (type) {
  if (type === "ascending") {
    self.arr = self.arr.sort(ascendingComparator);
    type = "descending";
  } else {
    self.arr = self.arr.sort(descendingComparator);
    type = "ascending";
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...