最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Sorting an array of objects on both ascending and descending order on same click - Stack Overflow

programmeradmin6浏览0评论

I have an array of objects:

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>

Right now I have implemented a basic sorting logic below

JAVASCRIPT(AngularJS controller):

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

This JavaScript function is currently sorting it in ascending order only based on title. How do I write a logic that sorts it on either order, i.e. click1 should sort it in ascending and click2 should reverse and set it in descending? Basically reversing the sort everytime it is clicked.

I have an array of objects:

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>

Right now I have implemented a basic sorting logic below

JAVASCRIPT(AngularJS controller):

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

This JavaScript function is currently sorting it in ascending order only based on title. How do I write a logic that sorts it on either order, i.e. click1 should sort it in ascending and click2 should reverse and set it in descending? Basically reversing the sort everytime it is clicked.

Share Improve this question asked Jun 28, 2019 at 15:41 azrael vazrael v 2816 silver badges18 bronze badges 2
  • reverse the > to < and create a variable that can store the currently sort order. – Sasha Commented Jun 28, 2019 at 15:49
  • Use a closure, and make the sorting function generic, – Teemu Commented Jun 28, 2019 at 16:08
Add a ment  | 

6 Answers 6

Reset to default 2

You can create a property on self like isAscending and default to true or false (whatever you want initially) based on which sort order will be executed and flip isAscending every time the sort fn runs.

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;
}

It probably would make sense to have a reusable function you can call to do the sorting for you which also accepts a 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))

You can replace the last param to deal with asc/desc if you need to.

Also since you are paring strings the remended way is to use String.localeCompare simply due to the amount of options it supports which almost always e in handy (sorting book10 vs book1 for example)

You can declare an auxiliary variable to help you decide which is the next direction in which you need to sort your array. Somehting like this:

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;
    }
}

You just need to maintain sort type somewhere so that you can toggle it.

There's lots of variants, but something simple like this should work:

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";
  }
}

Add a variable to your function and change the conditional

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);
    }
}

Create a boolean variable that is set to false. In your sortTitle() function create a condition that will detect whether it's true or false and then run the opposite when it's true.

发布评论

评论列表(0)

  1. 暂无评论