Clinton Green
Clinton Green

Reputation: 9977

Vue js: Prevent Sort from sorting array items, I only need the result

I'm following a tutorial where you can vote for a Mayoral Candidate. It has a sort function applied to it to determine the winner. However the sort function also sorts the candidates in real time. I want to prevent this because the Candidate Name and Vote buttons should not move up or down. I only need the sort function for the result.

HTML

<div class="container">

  <div id="mayor-vote">
    <h2>Mayor Vote</h2>
    <ul class="list-group" style="width: 400px;">
      <li v-for="candidate in candidates" class="list-group-item clearfix">
        <div class="pull-left">
          <strong style="display: inline-block; width: 100px;">{{ candidate.name }}:</strong> {{ candidate.votes }}
        </div>
        <button class="btn btn-sm btn-primary pull-right" @click="candidate.votes++">Vote</button>
      </li>
    </ul>
    <h2>Our Mayor is <span class="the-winner" :class="textClass">{{ mayor.name }}</span></h2>
    <button @click="clear" class="btn btn-default">Reset Votes</button>
    <br><br>
    <pre>
      {{ $data }}
    </pre>
  </div>

</div>

JS - refer to computed property

 new Vue({

  el: '#mayor-vote',

  data: {
    candidates: [
      { name: "Mr. Black", votes: 140 },
      { name: "Mr. Red", votes: 135 },
      { name: "Mr. Pink", votes: 145 },
      { name: "Mr. Brown", votes: 140 }
    ]
  },

  computed: {
    mayor: function(){
      var candidateSorted = this.candidates.sort(function(a,b){
        return b.votes - a.votes;
      });
      return candidateSorted[0];
    },
    textClass: function() {
      return this.mayor.name.replace(/ /g,'').replace('Mr.','').toLowerCase();
    }
  },

  methods: {
    clear: function() {
      this.candidates = this.candidates.map( function(candidate){
        candidate.votes = 0;
        return candidate;
      })
    }
  }
});

Here's a working version, https://jsfiddle.net/7dadjbzs/

Upvotes: 1

Views: 813

Answers (1)

Saurabh
Saurabh

Reputation: 73609

If you just want to get the mayor, i. e. the candidate with maximum votes, you don't need to sort the array, you can just find the candidate with max votes, and return it, like following. This will prevent rearranging the candidate, as you are not modifying the array.

  computed: {
    mayor: function(){
      return this.candidates.slice(0).sort(
 function(x, y) { return y.votes - x.votes })[0]
    },

see updated fiddle.

Upvotes: 2

Related Questions