0

I have this year-month-value array with data from gsheet:

2019 - Mar - 3
2019 - Mar - 1
2019 - Feb - 1
2019 - Feb - 1
2019 - Feb - 1
2019 - Feb - 1
2019 - Feb - 3
2019 - Feb -
2019 - Feb - 2
2019 - Feb - 1
2019 - Feb - 1
2019 - Jan - 1
2019 - Jan - 1
2019 - Jan - 1
2019 - Jan - 1

I want to sum the total values for each month like this:

2019 - Mar - 4
2019 - Feb - 11
2019 - Jan - 4

This is my code now:

<div class="row" id="list">
  <div v-for="entry in entries" v-if="entry.gsx$regionofincident.$t === 'Mediterranean'">
    <span>{{entry.gsx$reportedyear.$t}} - {{entry.gsx$reportedmonth.$t}} - {{entry.gsx$numberdead.$t}}</span>
  </div>
</div>

How do I sum the monthly values? Where do I do the operations? In js or html?

1 Answer 1

2

You can use a computed property to filter the Mediterranean items, and then use Array.prototype.reduce to tally the results:

computed: {
  medEntries() {
    const tally = this.entries
      // only process Mediterranean items
      .filter(entry => entry.gsx$regionofincident.$t === 'Mediterranean')

      // tally results
      .reduce((obj, entry) => {
        const key = entry.gsx$reportedyear.$t + entry.gsx$reportedmonth.$t
        const val = obj[key]
        const numDead = Number(entry.gsx$numberdead.$t || 0)

        if (val) {
          val.gsx$numberdead.$t = Number(val.gsx$numberdead.$t) + numDead
        } else {
          obj[key] = entry
        }
        return obj
      }, {})

    return Object.values(tally)
  }
}

Then replace entries in your template with the computed property name (medEntries):

<div v-for="entry in medEntries">...</div>

const entry = (year, month, numDead) => ({
  gsx$regionofincident: { $t : 'Mediterranean' },
  gsx$reportedmonth: { $t: month },
  gsx$reportedyear: { $t: year },
  gsx$numberdead: { $t: numDead },
})

const entries = [
  entry('2019', 'Mar', '3'),
  entry('2019', 'Mar', '1'),
  entry('2019', 'Feb', '1'),
  entry('2019', 'Feb', '1'),
  entry('2019', 'Feb', '1'),
  entry('2019', 'Feb', '1'),
  entry('2019', 'Feb', '3'),
  entry('2019', 'Feb'),
  entry('2019', 'Feb', '2'),
  entry('2019', 'Feb', '1'),
  entry('2019', 'Feb', '1'),
  entry('2019', 'Jan', '1'),
  entry('2019', 'Jan', '1'),
  entry('2019', 'Jan', '1'),
  entry('2019', 'Jan', '1'),
]

new Vue({
  el: '#app',
  data() {
    return {
      entries
    }
  },
  computed: {
    medEntries() {
      const tally = this.entries
        .filter(entry => entry.gsx$regionofincident.$t === 'Mediterranean')
        .reduce((obj, entry) => {
          const key = entry.gsx$reportedyear.$t + entry.gsx$reportedmonth.$t
          const val = obj[key]
          const numDead = Number(entry.gsx$numberdead.$t || 0)

          if (val) {
            val.gsx$numberdead.$t = Number(val.gsx$numberdead.$t) + numDead
          } else {
            obj[key] = entry
          }
          return obj
        }, {})

      return Object.values(tally)
    }
  }
})
<script src="https://unpkg.com/[email protected]"></script>

<div id="app">
  <div v-for="entry in medEntries">
    <span>{{entry.gsx$reportedyear.$t}} - {{entry.gsx$reportedmonth.$t}} - {{entry.gsx$numberdead.$t}}</span>
  </div>
</div>

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

3 Comments

Thank you Tony. My entries coming from gsheet and I don't know how integrate your code with mine. I update the code above
@user2208245 You should already have a data property named entries (based on the code in the question). You just need to copy the computed and template changes from my answer. No need to copy my data-setup code (i.e., don't copy const entry or const entries[]).
I tried, thank you very much for your help... I think I have to start a course for Vue.js :) This is my codepen codepen.io/manlioma/pen/BEWQXm

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.