【问题标题】:Split string into List<int> ignore none int values将字符串拆分为 List<int> 忽略无 int 值
【发布时间】:2014-04-18 01:38:42
【问题描述】:

我使用以下代码将字符串拆分为 List,但有时字符串包含非整数值,它们的处理方式不同。

示例字符串可能类似于:1,2,3,4,x

代码如下:

List<int> arrCMs = new List<int>(strMyList.Split(',').Select(x => int.Parse(x)));

问题是只要它碰到“x”就会抛出错误,因为“x”不能被解析为整数。

如何让它忽略非整数值?我确信我应该能够用 int.TryParse 做点什么,但我不太明白。

谢谢

【问题讨论】:

    标签: c# asp.net-mvc string


    【解决方案1】:
    List<int> arrCMs = strMyList.Split(',')
        .Select(possibleIntegerAsString => {
            int parsedInteger = 0;
            bool isInteger = int.TryParse(possibleIntegerAsString , out parsedInteger);
            return new {isInteger, parsedInteger};
        })
        .Where(tryParseResult => tryParseResult.isInteger)
        .Select(tryParseResult => tryParseResult.parsedInteger)
        .ToList();
    

    上例中的第一个Select 返回一个anonymous type,它描述了int.TryParse 的结果——也就是说,它是否是一个有效的整数,如果是,值是什么。

    Where 子句过滤掉那些无效的。

    第二个Select 然后从能够被解析的字符串中检索解析的值。

    【讨论】:

    • 很好,虽然我认为 Andrew 的回答稍微好一点。
    【解决方案2】:

    短而甜,使用int.TryParse

    List<int> nums = list
        .Split(',')
        .Select(i => 
        { 
            int val;
            return int.TryParse(i, out val) ? (int?)val : null;
        })
        .Where(i => i.HasValue)
        .Cast<int>()
        .ToList()
    

    工作示例: http://dotnetfiddle.net/4wyoAM

    【讨论】:

    • +1 表示您不必使用匿名类型。
    【解决方案3】:

    改变这个

    int result;
    List<int> arrCMs =
                new List<int>(strMyList.Split(',')
                                        .Where(x => int.TryParse(x, out result))
                                        .Select(int.Parse));
    

    【讨论】:

    • 您忘记了out 关键字。
    • 另外,将字符串转换为 int 会失败。
    • 不错的解决方案,但它的性能很差,因为你最终解析了两次。
    【解决方案4】:

    另一个,使用Array.ForEach

    List<int> ints = new List<int>();
    Array.ForEach(strMyList.Split(','), s =>
        {
            int i;
            if (int.TryParse(s, out i)){ ints.Add(i);}
        });
    

    【讨论】:

      【解决方案5】:

      情节转折:使用老式的foreach 循环。

      List<int> arrCMs = new List<int>();
      foreach (string str in strMyList.Split(new [] { ',' }, StringSplitOptions.RemoveEmptyEntries))
      {
          int res;
          if (int.TryParse(str, out res))
          {
              arrCMs.Add(res);
          }
      }    
      

      你也可以通过yield return为它创建一个方法并使用一个迭代器块:

      public static IEnumerable<int> ParseIntegers(string val, char seperator = ',')
      {
          foreach (string str in val.Split(new [] { seperator }, StringSplitOptions.RemoveEmptyEntries))
          {
              int res;
              if (int.TryParse(str, out res))
              {
                  yield return res;
              }
          }
      }
      

      如果只使用一次,这可能是过度设计。

      【讨论】:

        【解决方案6】:

        每个值只解析一次,但有点棘手。

        int result = 0;
        List<int> arrCMs = strMyList.Split(',')
                                    .Where(x => int.TryParse(x, out result))
                                    .Select(x => result)
                                    .ToList();
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-04-23
          • 1970-01-01
          • 2017-07-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-29
          • 1970-01-01
          相关资源
          最近更新 更多