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
6 Answers
Reset to default 2You 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.