鉴于各种口袋妖怪战斗的JSON:
[
{
"battleID": "1",
"trainers": [
{
"LastName": "Ketchum",
"ForeName": "Ash"
},
{
"LastName": "Mason",
"ForeName": "Misty"
}
]
},
{
"battleID": "2",
"trainers": [
{
"LastName": "Mason",
"ForeName": "Misty"
},
{
"LastName": "Brock",
"ForeName": "Stuart"
},
{
"LastName": "Ian",
"ForeName": "Foster"
}
]
},
{
"battleID": "3",
"trainers": [
{
"LastName": "Brock",
"ForeName": "Stuart"
},
{
"LastName": "Ketchum",
"ForeName": "Ash"
}
]
}
]
我想映射一个网格,计算两个Pokemon训练师/玩家之间的匹配数量。一场比赛最多可同时有4名球员。
Ash Ketchum Misty Mason Brock Stuart Ian Foster
Ash Ketchum 2 1 1 0
Misty Mason 1 2 1 1
Brock Stuart 1 1 2 1
Ian Foster 0 1 1 1
我的代码:
class Trainer {
constructor(firstname, lastname) {
this.firstname = firstname;
this.lastname = lastname;
}
coBattles(trainer) {
var battles = 0;
jsonData.map(x => {
x.trainers.map(y => {
if (this.firstname === y.ForeName && this.lastname === y.LastName) {
x.trainers.map(z => {
if (trainer.firstname === z.ForeName && trainer.lastname === z.LastName)
battles++;
});
}
});
});
return battles;
}
}
var pokemonTrainers = [];
// Currently Undesirable as I want a 'unique' array of all participating trainers.
jsonData.forEach(x => {
x.trainers.forEach(y => {
var trainer = new Trainer(y.ForeName, y.LastName);
pokemonTrainers.push(trainer);
});
});
//Battles between Misty Mason and Brock Stuart
console.log(pokemonTrainers[1].coBattles(pokemonTrainers[3]));
//returns 1
我正在寻找建议,如果我能在vanilla JS /第三方库中做得更好。如何才能使这个效率足以处理大量战斗数据(数百万)。
答案 0 :(得分:0)
你可以先得到所有独特的玩家名字,然后为每个玩家构建一个对象,作为一个值,另一个对象包含每个玩家的名字,包括他自己。然后你只需要循环数据并增加该对象的值,最后构建表。
var data = [{"battleID":"1","trainers":[{"LastName":"Ketchum","ForeName":"Ash"},{"LastName":"Mason","ForeName":"Misty"}]},{"battleID":"2","trainers":[{"LastName":"Mason","ForeName":"Misty"},{"LastName":"Brock","ForeName":"Stuart"},{"LastName":"Ian","ForeName":"Foster"}]},{"battleID":"3","trainers":[{"LastName":"Brock","ForeName":"Stuart"},{"LastName":"Ketchum","ForeName":"Ash"}]}]
var players = {}
var result = {}
// Get all names
data.forEach(function(e) {
e.trainers.forEach(function(p) {
players[p.LastName + ' ' + p.ForeName] = 1
})
})
// Add to result object
Object.keys(players).forEach(function(name) {
Object.keys(players).forEach(function(e) {
result[name] = Object.assign(result[name] || {}, {[e]: 0})
})
})
// Increment values
data.forEach(function(e) {
e.trainers.forEach(function(a, j) {
e.trainers.forEach(function(c, i) {
result[a.LastName + ' ' + a.ForeName][c.LastName + ' ' + c.ForeName]++
})
})
})
var table = document.body.querySelector('table');
var thead = '<tr><td></td><td>' + Object.keys(result).join('</td><td>') + '</td></tr>';
table.innerHTML += thead
for (var key in result) {
var cells = '';
for (var i in result[key]) {
cells += '<td>' + result[key][i] + '</td>';
}
var row = '<tr><td>' + key + cells + '</td></tr>';
table.innerHTML += row;
}
td:not(:first-child) {
text-align: center;
}
<table></table>
答案 1 :(得分:0)
使用2D地图结构,您可以按如下方式执行此操作;此代码将返回一个地图,其中每个键(播放器的名称)包含另一个地图,其中包含与竞争对手一起玩的名称和匹配数。
function getPlayedMatches(a){
return a.reduce(function(r,b){
var nl = b.trainers.map(t => t.ForeName + " " + t.LastName);
return nl.reduce((m,tn) => m.has(tn) ? m.set(tn, nl.reduce((sm,t) => sm.has(t) ? sm.set(t,sm.get(t)+1)
: sm.set(t,1), m.get(tn)))
: m.set(tn,new Map(nl.map(n => [n,1]))), r);
}, new Map);
}
var matches = [{"battleID":"1","trainers":[{"LastName":"Ketchum","ForeName":"Ash"},{"LastName":"Mason","ForeName":"Misty"}]},{"battleID":"2","trainers":[{"LastName":"Mason","ForeName":"Misty"},{"LastName":"Brock","ForeName":"Stuart"},{"LastName":"Ian","ForeName":"Foster"}]},{"battleID":"3","trainers":[{"LastName":"Brock","ForeName":"Stuart"},{"LastName":"Ketchum","ForeName":"Ash"}]}],
result = getPlayedMatches(matches);
console.log(function arrayifyMap(m){
return m.constructor === Map ? [...m].map(([v,k]) => [arrayifyMap(v),arrayifyMap(k)])
: m;
}(result));
&#13;