使用Underscore.js在嵌套集合中查找对象

时间:2014-04-06 15:16:51

标签: javascript jquery underscore.js

我有一组球队(在联赛中),如此:

var fra1 = {
   "sports":[
      {
         "name":"soccer",
         "id":600,
         "uid":"s:600",
         "leagues":[
            {
               "name":"French Ligue 1",
               "abbreviation":"fra.1",
               "id":710,
               "isTournament":false,
               "country":{
                  "id":7,
                  "name":"France",
                  "abbreviation":"FRA"
               },
               "uid":"s:600~l:710",
               "groupId":9,
               "shortName":"Ligue 1",
               "teams":[
                  {
                     "id":159,
                     "uid":"s:600~t:159",
                     "location":"Bordeaux",
                     "name":"Bordeaux",
                     "nickname":"Bordeaux",
                     "abbreviation":"BOR",
                     "color":"00003e",
                  },
                  {
                     "id":160,
                     "uid":"s:600~t:160",
                     "location":"Paris Saint-Germain ",
                     "name":"Paris Saint-Germain ",
                     "nickname":"Paris Saint-Germain ",
                     "abbreviation":"PSG",
                     "color":"000040",
                  }
               ]
            }
         ]
      }
   ],
}

每个var中大约有20个团队以这种方式存储。然后,我有大约六个这样的联赛:eng1esp1fra1ger1ita1usa1。我把它们放在另一个集合中,如下:

var all = {
    "eng1":eng1,
    "esp1":esp1,
    "fra1":fra1,
    "ger1":ger1,
    "ita1":ita1,
    "usa1":usa1
}

现在,每个团队(无论他们在哪个联盟中)都有一个唯一的ID:在上面的例子中,波尔多有ID 159,PSG有ID 160,依此类推。因此,我希望能够使用Underscore.js在all集合中搜索teamid一个独特的团队,但我无法完全理解语法。我知道我可以像这样搜索一个联盟:

var obj = _.find(fra1.sports[0].leagues[0].teams, function(obj) { return obj.id == teamid })

但我无法弄清楚如何在所有六个联赛中做到这一点。有人可以帮忙吗?我不想手动将这些集合合并为一个,这对于涉及的数据量来说很麻烦。

编辑:我目前正在使用:

for (var league in all)
{
    var obj = _.find(all[league].sports[0].leagues[0].teams, function(obj) { return obj.id == teamid })

    if (obj !== undefined)
    {   
        // do things
    }
}

但是仍然会喜欢更好的东西。

3 个答案:

答案 0 :(得分:1)

一种解决方案是创建团队地图,其中团队ID为关键,团队为值:

var teams = {};

_.each(all, function(nation){
    _.each(nation.sports[0].leagues[0].teams, function(team){
        teams[team.id] = team;
    });
});

然后,您可以使用密钥访问团队:

var psg = teams[160];

答案 1 :(得分:1)

就解析其他团队而言,只需使用链:

var allTeams = _.chain(all)
  .values()
  .pluck('sports').flatten()  // once
  .pluck('leagues').flatten() // twice
  .pluck('teams').flatten()   // third time's a charm
  .value()

我建议在teamID上使用_.groupBy()。这将为您提供映射teamID -> teamObject的哈希表(JS对象)。假设您的团队解析如下:

var allTeams =[
{
  "id":159,
  "uid":"s:600~t:159",
  "location":"Bordeaux",
  "name":"Bordeaux",
  "nickname":"Bordeaux",
  "abbreviation":"BOR",
  "color":"00003e",
},{
  "id":160,
  "uid":"s:600~t:160",
  "location":"Paris Saint-Germain ",
  "name":"Paris Saint-Germain ",
  "nickname":"Paris Saint-Germain ",
  "abbreviation":"PSG",
  "color":"000040",
}]

您可以将它们分组:

var lookup = _.groupBy(teams, 'id')

然后查找一个这样的团队:

var myTeam = lookup[teamId]

答案 2 :(得分:0)

只需在sportsleagues上执行其他循环,而不仅仅是all

for (var league in all) {
    var sports = all[league];
    for (var i=0; i<sports.length; i++) {
        var leagues = sports[i].leagues;
        for (var j=0; j<leagues.length; j++) {
            var teams = leagues[j].teams;
            // var obj = _.find(teams, function(obj) { return obj.id == teamid })
            for (var k=0; k<teams.length; k++) {
                var obj = teams[k];
                if (obj.id == teamid) {
                    … // do things
                }
            }
        }
    }
}