Kristian Vybiral
Kristian Vybiral

Reputation: 539

Count number of occurrence of value in data items

I am trying to count the number of times each value occurs for 'classtext' which is in data.items

However, by adding a function below to do that for each new inputted classtext on button click, I get 0 returned, even if I previously input several 'test' in the classtext field. I am very new in vuejs so obviously I am doing something wrong.

The code looks like this:

<!DOCTYPE html>
<html>
<script src="https://vuejs.org/js/vue.js"></script>
<style>
/* Vue List Item transition */
.list-item-enter-active,
.list-item-leave-active {
  transition: opacity 0.3s, -webkit-transform 0.3s;
  transition: opacity 0.3s, transform 0.3s;
  transition: opacity 0.3s, transform 0.3s, -webkit-transform 0.3s;
  -webkit-transform-origin: left center;
          transform-origin: left center;
}
.list-item-enter,
.list-item-leave-to {
  opacity: 0;
  -webkit-transform: scale(0.5);
          transform: scale(0.5);
}
/* //////////////////////////////////////// */
/* Basic Styles */
html {
  background: #eee;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}
.list {
  background: #FFF;
  margin: auto;
  padding: 1em 1em 1em;
  box-shadow: 0 5px 30px rgba(0, 0, 0, 0.2);
}
.list :last-child {
  margin-bottom: 0;
}
.list__ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
}
.list__input {
  display: flex;
  margin-bottom: 0.5em;
}
.list__item {
  display: block;
  margin-bottom: 0.25em;
}

</style>
</head>

<body>
  <div id="example-1" class="list">

  <div class="list__input" @keydown.enter="add">
    <button v-on:click="count">+</button>
    <input v-model="newBeneficiary" placeholder="Add beneficiary"  />
    <input v-model="newClass" placeholder="Add new task topic" />
    <input v-model="newItem" placeholder="Add new task text"  />
  </div>

  <transition-group name="list-item" tag="ul" class="list__ul">
    <li class="list__item" v-for="item in items" :key="item">
      Timestamp: {{ item.timestamp }} <br />
      Beneficiary: {{ item.beneficiarytext }} <br />
      Topic: {{ item.classtext }} <br />
      Task: {{ item.message }}
    </li>
  </transition-group>

</div>
</body>
<script>
/**
 * Return a timestamp with the format "m/d/yy h:MM:ss TT"
 * @type {Date}
 */

function timeStamp() {
  var now = new Date();
  var date = [ now.getMonth() + 1, now.getDate(), now.getFullYear() ];
  var time = [ now.getHours(), now.getMinutes(), now.getSeconds() ];
  var suffix = ( time[0] < 12 ) ? "AM" : "PM";
  time[0] = ( time[0] < 12 ) ? time[0] : time[0] - 12;
  time[0] = time[0] || 12;
  for ( var i = 1; i < 3; i++ ) {
    if ( time[i] < 10 ) {
      time[i] = "0" + time[i];
    }
  }
  return date.join("/") + " " + time.join(":") + " " + suffix;
}

var app = new Vue({
  el: '#example-1',
  data: {
    items: [
      /*{ timestamp:'testdate', beneficiarytext: 'TestBeneficiary', classtext: 'TestTopic', message: 'TestMessage' }*/
    ]
  },
  methods: {
    /* MIGHT BE USED LATER TO DELETE TASKS
    remove: function(item){
      this.items.splice( this.items.indexOf(item), 1 );
    },
    */
    add: function(){
      this.items.unshift({ timestamp: timeStamp(), beneficiarytext: this.newBeneficiary, classtext: this.newClass, message: this.newItem });
      this.newItem = '';
      console.log(this.items);
    },
    count: function() {
      var counting = this.items.reduce(function (n, class1) {
      return n + (class1.classtext == this.newClass);
    }, 0)}
  }
})
</script>
</body>

</html>

Upvotes: 0

Views: 484

Answers (1)

Decade Moon
Decade Moon

Reputation: 34286

You didn't bind this to the reducer function. Use

this.items.reduce((n, class1) => { ... })

or

this.items.reduce(function (n, class1) { ... }.bind(this))

See How does the “this” keyword work?.


The compute the counts for each classtext in the array:

this.items.reduce((map, item) => {
  map.set(item.classtext, (map.get(item.classtext) || 0) + 1)
  return map
}, new Map())

// Returns Map of (classtext, count) pairs:
// {
//   apple => 2,
//   banana => 6,
// }

Upvotes: 1

Related Questions