[Vuejs]-How to sum up values and remove duplicates from external API

0👍

Rather than working with the data as it comes in, make up your template as if you have the data in whatever format is convenient, then try to write a function to transform the data into that format.

In this case, I wanted to iterate the groups, and have each group contain its teams. I wound up with nested objects.

const axiosPromise = Promise.resolve([{
    Group: "A",
    Home: "Fc Barcelona",
    Away: "Fc Porto",
    Score: {
      Home: 0,
      Away: 0
    }
  },
  {
    Group: "A",
    Home: "AC Milan",
    Away: "Fc Barcelona",
    Score: {
      Home: 0,
      Away: 1
    }
  },
  {
    Group: "A",
    Home: "FC Barcelona",
    Away: "AC Milan",
    Score: {
      Home: 2,
      Away: 0
    }
  },
  {
    Group: "B",
    Home: "Juventus",
    Away: "Real Madrid",
    Score: {
      Home: 0,
      Away: 1
    }
  }
]);

new Vue({
  el: '#app',
  data: {
    groups: {}
  },
  mounted() {
    axiosPromise.then((results) => this.transformResults(results));
  },
  methods: {
    transformResults(axiosResults) {
      const result = {};
      axiosResults.forEach((obj) => {
        if (!(obj.Group in result)) {
          result[obj.Group] = {};
        }
        const g = result[obj.Group];
        if (!(obj.Home in g)) {
          g[obj.Home] = 0;
        }
        if (!(obj.Away in g)) {
          g[obj.Away] = 0;
        }
        g[obj.Home] += obj.Score.Home;
        g[obj.Away] += obj.Score.Away;
      });
      this.groups = result;
    }
  }
});
table {
  border-collapse: collapse;
  margin: 1rem 0;
  outline: thin solid black;
}

th,
td {
  border: thin solid gray;
  padding: 0 0.5rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div v-for="(g, name) in groups">
    Group: {{name}}
    <table>
      <tr>
        <th>Team</th>
        <th>Points</th>
      </tr>
      <tr v-for="(points, name) in g">
        <template v-if="points > 0">
          <td>{{name}}</td>
          <td>{{points}}</td>
        </template>
      </tr>
    </table>
  </div>
</div>

0👍

Here is an example hot to solve your problem (with console.log). Your data contains different names for the same club (Fc Barcelona, FC Barcelona). Use toLowerCase/toUpperCase or other function to normalize your data.

var groupBy = function(xs, key) {
  return xs.reduce(function(rv, x) {
    (rv[x[key]] = rv[x[key]] || []).push(x);
    return rv;
  }, {});
};

const results = [
{
Group:"A",
Home: "FC Barcelona",
Away: "FC Porto",
Score: {
Home: 0,
Away: 0
},
},
{
Group:"A",
Home: "AC Milan",
Away: "FC Barcelona",
Score: {
Home: 0,
Away: 1
},
},
{
Group:"A",
Home: "FC Barcelona",
Away: "AC Milan",
Score: {
Home: 2,
Away: 0
},
},
{
Group:"B",
Home: "Juventus",
Away: "Real Madrid",
Score: {
Home: 0,
Away: 1
}
}
]

const groupGames = groupBy(results, 'Group')


const m = new Map()

for(let key in groupGames) {
  const group = groupGames[key]
 	const results = new Map()
  
  group.forEach(game => {
  	if (!results.has(game.Home)) {
    	results.set(game.Home, { pts: 0 })
    } 
    let home = results.get(game.Home)
    
    if (!results.has(game.Away)) {
    	results.set(game.Away, { pts: 0 })
    } 
    let away = results.get(game.Away)
    
    if (game.Score.Home === game.Score.Away) {
    	home.pts += 1
      away.pts += 1
    }
    
    if (game.Score.Home > game.Score.Away) {
    	home.pts += 3
    }
    
    if (game.Score.Home < game.Score.Away) {
    	away.pts += 3
    }
  })
  
  m.set(key, results)
}

m.forEach((value, key) => {
	console.log('Group:', key)
  
  value.forEach((v, k) => {
  	console.log('Club:', k, 'Points:', v.pts)
  })
})

And output

Group: A
Club: FC Barcelona Points: 7
Club: FC Porto Points: 1
Club: AC Milan Points: 0
Group: B
Club: Juventus Points: 0
Club: Real Madrid Points: 3

Leave a comment