Reputation: 6974
How Can I sort Array object for two properties like "surname" - "name"?
I tried with concatenation but It doesn't works, because it sort only for second sorting:
computed:{
sortedArray: function() {
function name(a, b) {
if (a.name < b.name) return -1;
if (a.name > b.name) return 1;
return 0;
}
function surname(a, b) {
if (a.surname < b.surname) return -1;
if (a.surname > b.surname) return 1;
return 0;
}
return this.users.sort(surname).sort(name);
}
}
I 'have tried also with:
function surname(a, b) {
return a.surname < b.surname || a.name < b.name
}
But it return an array not sorted by surname / name
Upvotes: 1
Views: 4064
Reputation: 135872
You are actually pretty close.
The problem is when you do:
return this.users.sort(surname).sort(name);
You first sort by surname
and then by name
ignoring surname
.
The solution is to use a function that handles both properties at the same time. So join those sort functions into one.
Another thing, your computed is sorting in-place. You probably want to clone the array and return a sorted copy in the computed property instead.
new Vue({
el: '#app',
data: {
users: [
{name: "John", surname: "Nash"},
{name: "Paul", surname: "Pringles"},
{name: "Bob", surname: "Pringles"},
{name: "Bob", surname: "Abbey"},
{name: "Alice", surname: "Abbey"},
]
},
computed:{
sortedArray: function() {
function surnameName(a, b) {
if (a.surname < b.surname) return -1;
if (a.surname > b.surname) return 1;
if (a.name < b.name) return -1;
if (a.name > b.name) return 1;
return 0;
}
// return this.users.sort(surnameName); // sorts in-place
return [...this.users].sort(surnameName); // shallow clone + sort
}
}
})
<script src="https://unpkg.com/vue"></script>
<div id="app">
<p>unsorted:<br>{{ users }}</p>
<p>sorted:<br>{{ sortedArray }}</p>
</div>
Upvotes: 2