【问题标题】:Finding object in nested collection with Underscore.js使用 Underscore.js 在嵌套集合中查找对象
【发布时间】:2014-05-18 17:16:46
【问题描述】:

我有一组球队(在一个联赛中),如下所示:

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,巴黎圣日耳曼的 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
    }
}

但仍然想要更好的东西。

【问题讨论】:

    标签: javascript jquery underscore.js


    【解决方案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];
    

    【讨论】:

    • 这假设每个国家只有一项运动,每项运动只有一项联赛。
    • OP 当前使用的是什么。
    • 好点,我仍然更喜欢 _.groupBy 循环使用 _.each 并手动构建映射。
    【解决方案2】:

    至于解析其余团队,只需使用链:

    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]
    

    【讨论】:

      【解决方案3】:

      只需在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
                      }
                  }
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2013-07-08
        • 2019-12-31
        • 1970-01-01
        • 2016-04-16
        • 1970-01-01
        • 2013-11-06
        • 1970-01-01
        • 1970-01-01
        • 2021-06-10
        相关资源
        最近更新 更多