【问题标题】:How to sum up values and remove duplicates from external API如何汇总值并从外部 API 中删除重复项
【发布时间】:2019-08-01 19:25:05
【问题描述】:

所以我有一个 api 可以为我提供这样的足球比赛结果:

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
}
]

等等……

除此之外,我想根据组来整理排名表,但我有团队重复,我无法根据分数从多场比赛中总结出一个团队的积分

到目前为止,我已经尝试使用我提供的代码中的 if 语句来解决它,如果有更好的解决方案,请告诉我!

<tbody v-for="result in results" :key="result.index">
    <div v-if="result.Group=='A'>
       <tr>
         <td>{{result.Home}}</td> <br> <-- i need teams to be print out once, not several times

        <td>{{result.Score.Home}}</td> <-- i need this to be 'if result.Score.Home>0 add 3 points to the adequate team and print it out here'

                        </tr>
                    </div>
                </tbody>

data () {
    return {
        results:[]
    }

mounted () {
    axios
      .get('http://localhost/soccer/results',)
      .then(response => (this.results = response.data))
}

使用示例中的代码,我将得到以下结果:

Team         Score      PTS
Fc Barcelona 0
Ac Milan 0 
Fc Barcelona 2

我需要做到这一点(不需要Score,需要根据Score计算PTS,并且像这样只打印一次团队):

Team         Score      PTS
Fc Barcelona  N/A       3
Ac Milan      N/A       0

【问题讨论】:

  • 不要尝试按原样使用您的数据。将其转换为可以在模板中直接使用的内容。
  • @RoyJ ,您好,感谢您的快速回答,您能给我一个简短的例子来说明如何实现这一点会很棒,谢谢

标签: javascript api vue.js ecmascript-6


【解决方案1】:

这是一个热的例子来解决你的问题(使用 console.log)。您的数据包含同一俱乐部的不同名称(巴塞罗那足球俱乐部、巴塞罗那足球俱乐部)。使用 toLowerCase/toUpperCase 或其他函数来规范化您的数据。

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)
  })
})

然后输出

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

【讨论】:

    【解决方案2】:

    与其直接处理传入的数据,不如按照方便的格式来构建模板,然后尝试编写一个函数将数据转换为该格式。

    在这种情况下,我想迭代组,并让每个组都包含其团队。我以嵌套对象结束。

    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>

    【讨论】:

    • 这项工作非常感谢你,但无论如何这个 const axiosResults 是否可以直接链接到在线 API 并动态获取信息?
    • 当然。让 transformResults 接受 axiosResults 作为参数。让您的 axios 获取挂载并从那里调用 transformResults
    • aha 所以基本上这个:mounted () { axios .get('http://',) .then(response => (this.axiosResults = response.data)) },我做吗需要在该代码中添加任何内容吗?而且我不明白你的代码是如何工作的,所以如果我想添加另一个属性,如点、名称等。: 如何在方法上命名属性所以我可以像你点的那样称呼他们,还有另一个名字?
    • 我应该添加什么?
    • 我已经编辑了答案中的代码,以便更清楚地了解如何将它与 axios Promise 一起使用。
    猜你喜欢
    相关资源
    最近更新 更多
    热门标签