【问题标题】:Javascript iterating nested loops and returning specific valuesJavascript迭代嵌套循环并返回特定值
【发布时间】:2018-11-15 20:56:19
【问题描述】:

我对 Javascript 非常陌生,并试图打印出选定的球队 NFL 赛程表。我已经创建并填充了包含所有团队的下拉菜单。我希望用户能够选择他们的团队并查看他们的日程安排。我能够返回整个列表(每场比赛),但我无法弄清楚如何只返回所选球队的比赛。这是我正在使用的数据的样子。

"Schedule": [
    {
      "gameId": "1",
      "gameWeek": "1",
      "gameDate": "2018-09-06",
      "awayTeam": "ATL",
      "homeTeam": "PHI",
      "gameTimeET": "8:20 PM",
      "tvStation": "NBC",
      "winner": "PHI"
    },
    {
      "gameId": "2",
      "gameWeek": "1",
      "gameDate": "2018-09-09",
      "awayTeam": "BUF",
      "homeTeam": "BAL",
      "gameTimeET": "1:00 PM",
      "tvStation": "CBS",
      "winner": "BAL"

这是返回我所有游戏的代码。

function processData(data){

  schedule = data["Schedule"];

  for(eachGame in schedule){
    var game = schedule[eachGame];
    var week = game["gameWeek"];
    var homeTeam = game["homeTeam"];
    var awayTeam = game["awayTeam"];
    var winner = game["winner"];
    var tableRow = "<tr><td>" + week + "</td><td>" + homeTeam + "</td><td>" + awayTeam + "</td><td>" + winner + "</td></tr>";
    $("#output").append(tableRow);

  }
}

当客队或主队是用户选择的球队时,我需要返回。

谢谢!

【问题讨论】:

  • 如何获得用户选择的团队?
  • 让团队 = $('#teamSelect').val();
  • 您可以使用filter() 来执行此操作。 let teamSchedule = schedule.filter(g =&gt; g.homeTeam === team || g.awayTeam === team);我没有提交这个作为答案,因为我觉得这个问题很可能是重复的。

标签: javascript arrays loops


【解决方案1】:

要将数组减少到只有少数几个项目,我几乎总是建议使用Array.filter(),但实际上我将首先针对您的情况提出一个替代解决方案。

如果您要使用 filter 循环遍历项目并找到您想要的项目,然后使用 for 循环将它们附加到表中,那么您将循环遍历某些相同的元素两次.

相反,我们可以应用我们的逻辑来跳过我们不希望在同一循环中的游戏,方法是执行以下操作:

//If "team" is neither the away team, nor the home team, skip this game
if (![game.awayTeam, game.homeTeam].includes(team)) return; 

示例 1:(已添加评论)

var data = { Schedule: [{ awayTeam: "Jets", homeTeam: "Bills", winner: "Bills", week: 1 }, { awayTeam: "Saints", homeTeam: "Cardinals", winner: "Cardinals", week: 1 }, { awayTeam: "Giants", homeTeam: "Bengals", winner: "Bengals", week: 2 }, { awayTeam: "Bills", homeTeam: "Jaguars", winner: "Bills", week: 2 }, { awayTeam: "Bills", homeTeam: "Patriots", winner: "Patriots", week: 3 } ] };

function setScheduleByTeam(team) {
  let schedule = data["Schedule"];    //Get the schedule
  var $outputTable = $("#output");    //Store the table as a variable
  $outputTable.find("tbody").empty(); //Empty out the current records

  schedule.forEach(function(game) {                             //For each game in the schedule
    if (![game.awayTeam, game.homeTeam].includes(team)) return; //Skip the record if our team isn't in it

    //Create + Append table row
    var tableRow = "<tr><td>" + game.week + "</td><td>" + game.homeTeam + "</td><td>" + game.awayTeam + "</td><td>" + game.winner + "</td></tr>";
    $outputTable.append(tableRow);
  });
}

//On button click
$("body").on("click", "button", function() {
  let team = $('#teamSelect').val();  //Get selected team
  setScheduleByTeam(team);            //Update the table to that team's schedule
});
td,th { padding: 5px 15px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="teamSelect">
  <option>Select Team</option>
  <option value="Bengals">Bengals</option>
  <option value="Bills">Bills</option>
  <option value="Jets">Jets</option>
</select>
<button>Go!</button>

<table id="output">
  <thead>
    <tr>
      <th>Week</th>
      <th>Home</th>
      <th>Away</th>
      <th>Winner</th>
    </tr>
  </thead>
</table>

但是,有些人可能会主张清洁,在这种情况下,我建议使用我之前提到的 filter 方法:

示例 2(已添加评论)

var data = { Schedule: [{ awayTeam: "Jets", homeTeam: "Bills", winner: "Bills", week: 1 }, { awayTeam: "Saints", homeTeam: "Cardinals", winner: "Cardinals", week: 1 }, { awayTeam: "Giants", homeTeam: "Bengals", winner: "Bengals", week: 2 }, { awayTeam: "Bills", homeTeam: "Jaguars", winner: "Bills", week: 2 }, { awayTeam: "Bills", homeTeam: "Patriots", winner: "Patriots", week: 3 } ] };

//Filter out schedule to only games where awayTeam == team OR homeTeam == team.
//Returns the filtered team's schedule
const getGamesByTeam = (team) => data.Schedule.filter(g => g.awayTeam == team || g.homeTeam == team);

function updateScheduleTable(games) {  
  var $outputTable = $("#output");     //Store table as variable
  $outputTable.find("tbody").empty();  //Remove existing rows
  
  games.forEach(function(game) {  //For each game, append to table
    var tableRow = "<tr><td>" + game.week + "</td><td>" + game.homeTeam + "</td><td>" + game.awayTeam + "</td><td>" + game.winner + "</td></tr>";
    $outputTable.append(tableRow);
  });
  
}

$("body").on("click", "button", function() {
  let team = $('#teamSelect').val();  //Get the selected team
  let games = getGamesByTeam(team);   //Get a filtered array of one team's schedule
  updateScheduleTable(games);         //Update the table based on that set of games
});
td,th { padding: 5px 15px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="teamSelect">
  <option>Select Team</option>
  <option value="Bengals">Bengals</option>
  <option value="Bills">Bills</option>
  <option value="Jets">Jets</option>
</select>
<button>Go!</button>

<table id="output">
  <thead>
    <tr>
      <th>Week</th>
      <th>Home</th>
      <th>Away</th>
      <th>Winner</th>
    </tr>
  </thead>
</table>

【讨论】:

    【解决方案2】:

    您需要根据用户选择的团队对数据数组进行排序。为此,您需要使用array method 循环遍历数组并根据您放入循环中的逻辑返回值。为此,我使用了reduce 方法(IMO 最有用的数组方法)。

    function filterForSelectedTeam(data) {
      const accumulator = [];
      const team = $('#teamSelect').val();
      const schedule = data["Schedule"];
      // if team has a value this reduce method will return a sorted array
      // based on the logic in the loop.
      return team && schedule.reduce((acc, game) => {
        if (game["homeTeam"] === team || game['awayTeam'] === team) {
          acc.push(game);
        };
        return acc;
      }, accumulator);
    }
    
    const data = [] // your data here;
    const gamesBySelectedTeam = filterForSelectedTeam(data)
    
    gamesBySelectedTeam.forEach(game => {
      const tableRow = "<tr><td>" + game['gameWeek'] + "</td><td>" + game['homeTeam'] + "</td><td>" + game['awayTeam'] + "</td><td>" + game['winner'] + "</td></tr>";
      $("#output").append(tableRow);
    });
    

    【讨论】:

    • 虽然reduce 非常适合您尝试从多对一转换,但如果您只是想过滤一个数组,那么使用.filter() 会更容易、更简洁。也就是说,最佳解决方案可能只是包括“我应该展示这个游戏吗?” forEach 中的逻辑,这样你就可以使用一个循环而不是两个循环:)
    • @TylerRoper,您应该提供您自己的过滤方法解决方案,以显示它有多“清洁和简单”。此外,我不会只是将所有逻辑推入 forEach 循环。我想展示减少,以便其他开发人员更容易阅读。如果有的话,我应该链接这两个循环。
    • 这只是一个建议。看来您已选择将其视为攻击。更何况,在你提交答案前几分钟,我在上面的cmets中写了一个单行过滤方法。
    • @TylerRoper 没有将其视为攻击。我只是指出,如果你有更好的解决方案,你应该提供它。这就是 SO 的全部意义所在。
    • @TylerRoper,这只是一种不同的思维方式而已。我通常使用reduce 而不是mapfilter,因为它实现了相同的目标,并且您还可以返回不同的类型。感谢您的帮助。
    【解决方案3】:

    这是一种只需几个方法调用就可以做到这一点的方法:

    function processData({ Schedule: s }, team) {
      // s is now the equivolent of data['Schedule']
      // Filter the data to get all games where either
      // the away of home team is the team sent in
      // Empty the table so it includes only those games appended below
      // Append the array of games as html elements
      $("#output")empty().append(
        s.filter(g => g.awayTeam === team || g.homeTeam === team)
        .map(g => {
          `<tr>
            <td>${game.gameWeek}</td>
            <td>${game.homeTeam}</td>
            <td>${game.awayTeam}</td>
            <td>${game.winner}</td>
          </tr>`
        })
      );
    }
    

    您可以将一组 html 字符串附加到 DOM 并得到正确处理。

    【讨论】:

      猜你喜欢
      • 2013-10-05
      • 2014-10-22
      • 1970-01-01
      • 2021-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-09
      相关资源
      最近更新 更多