有没有更好的方法来跟踪列表索引,同时迭代列表

时间:2014-04-28 13:48:50

标签: c# arrays list indexing iteration

目前,该方法使用for()循环和foreach()循环来迭代列表中的每个数组元素,以比较数组元素内的值。如果满足条件,我需要for循环来记录列表的当前索引值,以便我知道之后重建列表的位置。

// update high score list
public void updateScores()
{
    // if the list of scores isnt empty compare score
    if (list.Count() != 0)
    {
        // loop through each array in the list
        for (int i = 0; i <= list.Count(); i++)
        {
            // look into each linedata array in the list
            foreach (string[] ld in list)
            {
                // only look at scores that are the same difficulty
                if (lineData[1] == difficulty)
                {
                    // if score is greater than this score in list
                    if (score > Convert.ToInt32(lineData[0]))
                    {
                        // record which index the score was higher than
                        scoreIndex = i;
                    }
                }
            }
        }

        // if the score is higher than one of the saved highscores remove all lower score down one index
        for (int i = list.Count() - 1; i > scoreIndex; i--)
        {
            // continue
        }
    }
}

这是列表的构建方式:

// load highscores
public bool LoadScores()
{
    // attempt to load the highscore list
    if (File.Exists("highScores"))
    {
        // loop through each line in the file
        while ((line = file.ReadLine()) != null)
        {
            // seperate the score from the difficulty
            lineData = line.Split(',');

            // add each line to the list
            list.Add(lineData);
        }
        return true;
    }
    else{return false;}
}

highscores文本文件:

1231,1
1231232,2
4664,2
252,1
475532,1

问题:在迭代列表时是否有更好的方法来跟踪列表索引。

编辑:基本上我将球员得分与高分榜单进行比较。如果分数足够高,则较低的分数将向下移动以允许新分数进入列表

2 个答案:

答案 0 :(得分:6)

首先,谢尔盖是正确的;这段代码是大量的错误和不良做法。谢尔盖没有提到的两个是:

  • C#中的标准是PascalCase您的方法名称,而不是camelCase
  • 请勿在{{1​​}}上调用扩展方法Count()。使用IList属性。

我建议您养成编写相互调用的较小方法的习惯,然后仔细测试每个方法。

正如一些评论者指出的那样,您可以通过维护排序列表,将旧列表和新项目联合,对该序列进行排序,将其截断为仅包含前n个,将其转换为列表,你已经完成了。

这些都没有回答你的问题,这是

  

在迭代列表时是否有更好的方法来跟踪列表索引?

我向你提出,这不是一个非常正确的问题。一个更好的问题是:

  

如何确定列表中与给定条件匹配的第一项的索引?

在静态类中创建扩展方法:

Count

此扩展方法接受序列和谓词,并返回与谓词匹配的第一个项的索引;如果没有项与谓词匹配,则返回null。请注意,这适用于任何序列,而不仅仅是 public static int? FirstIndex<T>(this IEnumerable<T> items, Func<T, bool> predicate) { if (items == null) throw new ArgumentNullException("items"); if (predicate == null) throw new ArgumentNullException("predicate"); int index = 0; foreach (var item in items) { if (predicate(item)) return index; index += 1; } return null; } - IList索引器和[]属性未使用。

答案 1 :(得分:1)

序言:)

您是否尝试过执行代码? :)

  1. 你有一个错误:外部循环将用完列表范围。
  2. 通常不需要在迭代之前检查列表大小。
  3. 在执行updateScores之前,我没有看到任何排序列表的代码。您的代码将在未排序的列表中提供意外结果。
  4. 您现在正在使用字符串。排序字符串数组肯定不是你想要的。考虑使用带有整数的结构来获得高分值。
  5. 回答您的问题

    1. 您可以从外部循环开始内循环并使用break语句。见例:

      public void updateScores()
      {
          // loop through each array in the list
          for (int i = 0; i < list.Count(); i++)
          {
              string[] lineData = list[i];
              if (lineData[1] == difficulty)
              {
                  if (score > Convert.ToInt32(lineData[0]))
                  {
                      // if the score is higher than one of the saved highscores remove all lower score down one index
                      for (int j = list.Count() - 1; j > scoreIndex; j--)
                      {
                          // continue
                      }
                      break;
                  }
              }
          }
      }
      
    2. 否定条件可以简化代码:

      public void updateScores()
      {
          // loop through each array in the list
          for (int i = 0; i < list.Count(); i++)
          {
              string[] lineData = list[i];
              if (lineData[1] != difficulty)
                  continue;
              if (score <= Convert.ToInt32(lineData[0]))
                  continue;
              // if the score is higher than one of the saved highscores remove all lower score down one index
              for (int j = list.Count() - 1; j > scoreIndex; j--)
              {
                  // continue
              }
              break;
          }
      }