60

How can I sort an array by name or sex before displaying it in a v-for loop? https://jsfiddle.net/rg50h7hx/

<div id="string">
  <ul>
    <li v-for="array in arrays">{{ array.name }}</li>
  </ul>
</div>
// Vue.js v. 2.1.8
var string = new Vue({
  el: '#string',
  data: {
    arrays: [
      { name: 'kano',    sex: 'man' },
      { name: 'striker', sex: 'man' },
      { name: 'sonya',   sex: 'woman' },
      { name: 'sindell', sex: 'woman' },
      { name: 'subzero', sex: 'man' }
    ]
  }
})

Do I have to use a "computed", or whatever?

4
  • You might try making a getter method which sorts the array before returning. Edit: looks like that might be exactly what you're referring to by computed. See the documentation here: vuex.vuejs.org/en/getters.html Commented Mar 19, 2017 at 7:07
  • 1
    @Christopher Thank you. I wanted to study pure vue, maybe vuex for me is too difficult... Commented Mar 19, 2017 at 7:30
  • I think you would need to make sure to presort the data when it is set then. You could technically even do something like data: { arrays: [3, 2, 1].sort() }. Note you'll need to use the sort function with a callback to sort by an object property. Commented Mar 19, 2017 at 7:38
  • Try using filter before reverse: stackoverflow.com/a/67557323/3569935 Commented May 16, 2021 at 13:41

5 Answers 5

84

Yes, an easy way to do this can be create a computed property which can return the sortedArray, like following:

computed: {
  sortedArray: function() {
    function compare(a, b) {
      if (a.name < b.name)
        return -1;
      if (a.name > b.name)
        return 1;
      return 0;
    }

    return this.arrays.sort(compare);
  }
}

See working demo.

You can find the documentation of sort here which takes a compareFunction.

compareFunction Specifies a function that defines the sort order. If omitted, the array is sorted according to each character's Unicode code point value, according to the string conversion of each element.

Sign up to request clarification or add additional context in comments.

6 Comments

Can I ask you another question? Why are two functions used here? How does the second function know what exactly needs to be passed to A and what to B?
@user3798618 Please see added details, Let me know if any issue?
I had to add .toUpperCase() to a.name and b.name to make sure that it would not order capital letters first and lowercase second.
here, the computed property has a side effect, this.arrays is sorted on place so this.arrays and this.sortedArray share the same reference. You should clone the array and sort it if you want to use a computed property. If you want to sort this.arrays directly, use a watcher.
there have an error with unexpected side effects. . . .to avoid it please copy the main arrays. . . vue will complaint. . . ex: this.arrays.slice().sort(compare);
|
34

with arrow functions es6:

sortedArray(){
    return this.arrays.sort((a, b) => a.name - b.name );
}

4 Comments

Is there a similar concise way to sort this in the reverse order?
yes ,just reverse with Less than operator <, for instance this.arrays.sort((a, b) => a.name < b.name )
Note that > returns only 0 (equal) or 1 (greater) while sort compare function must return negative, zero or positive, otherwise sorting will be invalid. Instead of > use - for numbers: (a, b) => a - b, or write a valid compare function with if or anything. (see sort on MDN: mzl.la/2QcCQ8V)
a - b does not work for strings, as it returns NaN. The answer is wrong.
19

Html side

<div id="string">
      <ul>
        <li v-for="array in sortArrays(arrays)">{{ array.name }}</li>
      </ul>
    </div>

Vue js code || Using Lodash

var string = new Vue({
  el: '#string',
  data: {
    arrays: [
      { name: 'kano',    sex: 'man' },
      { name: 'striker', sex: 'man' },
      { name: 'sonya',   sex: 'woman' },
      { name: 'sindell', sex: 'woman' },
      { name: 'subzero', sex: 'man' }
    ]
  },
  methods: {
     sortArrays(arrays) {
            return _.orderBy(arrays, 'name', 'asc');
        }
  }
})
  • in orderBy function, first argument is array, 2nd argument is key (name / sex) 3rd argument is order (asc / desc)

1 Comment

your function is being called from a for loop and so for every item in the array, will your function be evaluated thereby hindering performance?
8

This works really cool:

sortFunc: function (){
  return this.arrays.slice().sort(function(a, b){
    return (a.name > b.name) ? 1 : -1;
  });
}

call the function from HTML:

<div id="string">
 <ul>
   <li v-for="array in sortFunc()">{{ array.name }}</li>
 </ul>
</div>

2 Comments

hi, thanks this worked well for me and I managed to get my table rows in descending order by using return (a.ID < b.ID) ? 1 : -1; the issue I have now is when I add a new row, it adds in the bottom table row rather than the top. here is the code I use to add the new row. this.breakData.unshift({ Name: "[New Break]", Active: this.filterAdd, Description: "", BreakTime: 5, IncludeInActiveTime: false, });
its ok, I fixed this issue by using push instead of unshift. hope this helps someone else.
0

Easy way; You can use computedArray instead of array

computed: {
computedFonksiyon() {
  this.arrays.sort(function(x, y) {
    return y.name- x.name;
  });
  return this.arrays;
}
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.