代码之家  ›  专栏  ›  技术社区  ›  CaffGeek

从字符串[]中选择整数,并返回int[]

  •  1
  • CaffGeek  · 技术社区  · 14 年前

    我有一个数组 string[] 值通常可转换为整数。

    var values = new [] {"", "1", "2", "a", "3"};
    

    var numbers = new [] {1, 2, 3};
    

    9 回复  |  直到 14 年前
        1
  •  4
  •   ChaosPandion    14 年前
    var numbers = values.Select(
        s => {
            int n;
            if (!int.TryParse((s ?? string.Empty), out n)) 
            {
                return (int?)null;
            }
            return (int?)n;
        }
    )
    .Where(n => n != null)
    .Select(n => n.Value)
    .ToArray();
    
        2
  •  4
  •   Bryan Watts    14 年前

    这是我的看法。它使用一个单独的方法,但干净地表示条件解析,而不使用可为null的值:

    private static IEnumerable<int> ParseInt32s(IEnumerable<string> value)
    {
        foreach(var value in values)
        {
            int n;
    
            if(Int32.TryParse(value, out n))
            {
                yield return n;
            }
        }
    }
    

    用法:

    string[] values;
    
    var parsedValues = ParseInt32s(values).ToArray();
    
        3
  •  3
  •   Community Daniel Roseman    7 年前

    我个人使用的扩展方法与其他人目前发布的有点不同。它专门使用一个自定义 WeakConverter<TSource, TResult> 委托以避免 Ron's answer 电话号码 ToString() 在保持泛型的同时 Jared's answer (尽管我承认,有时试图使所有的东西都通用化是过分的——但在这种情况下,额外的努力对于我认为在可重用性方面显著的好处来说并不是太多)。

    public delegate bool WeakConverter<TSource, TResult>(TSource source, out TResult result);
    
    public static IEnumerable<TResult> TryConvertAll<TSource, TResult>(this IEnumerable<TSource> source, WeakConverter<TSource, TResult> converter)
    {
        foreach (TSource original in source)
        {
            TResult converted;
            if (converter(original, out converted))
            {
                yield return converted;
            }
        }
    }
    

    有了它,您可以将 string[] int[]

    string[] strings = new[] { "1", "2", "abc", "3", "", "123" };
    
    int[] ints = strings.TryConvertAll<string, int>(int.TryParse).ToArray();
    
    foreach (int x in ints)
    {
        Console.WriteLine(x);
    }
    

    输出:

    1
    2
    3
    123
    
        4
  •  3
  •   Daniel Renshaw    14 年前

    这可以在单个linq语句中完成,而无需进行两次解析:

    var numbers = values
        .Select(c => { int i; return int.TryParse(c, out i) ? i : (int?)null; })
        .Where(c => c.HasValue)
        .Select(c => c.Value)
        .ToArray();
    
        5
  •  2
  •   Teekin    14 年前

    编辑:更新为不使用try/catch,因为StackOverflow用户指出它很慢。

    试试这个。

    var values = new[] { "", "1", "2", "a", "3" };
    List<int> numeric_list = new List();
    int num_try = 0;
    foreach (string string_value in values)
    {
        if (Int32.TryParse(string_value, out num_try) {
            numeric_list.Add(num_try);
        }
    
        /* BAD PRACTICE (as noted by other StackOverflow users)
        try
        {
            numeric_list.Add(Convert.ToInt32(string_value));
        }
        catch (Exception)
        {
            // Do nothing, since we want to skip.
        }
        */
    }
    
    return numeric_list.ToArray();
    
        6
  •  1
  •   JaredPar    14 年前

    你可以试试下面的方法

    public static IEnumerable<int> Convert(this IEnumerable<string> enumerable) {
      Func<string,int?> convertFunc = x => {
        int value ;
        bool ret = Int32.TryParse(x, out value);
        return ret ? (int?)value : null;
      };
      return enumerable
        .Select(convertFunc)
        .Where(x => x.HasValue)
        .Select(x => x.Value);
    }
    

    var numbers = values.Convert().ToArray();
    
        7
  •  1
  •   Ron Warholic    14 年前

    用一些简单的LINQ:

    var numbers = values.Where(x => { int num = 0; return Int32.TryParse(x, out num); })
                        .Select(num => Int32.Parse(num));
    

    public static IEnumerable<int> TryCastToInt<T>(this IEnumerable<T> values)
      int num = 0;
      foreach (object item in values) {
        if (Int32.TryParse(item.ToString(), num)) {
          yield return num;
        }
      }
    }
    
        8
  •  0
  •   Chris McCall    14 年前
    int n;
    var values = new[] { "", "1", "2", "a", "3" };
    var intsonly = values.Where (v=> Int32.TryParse(v, out n)).Select(x => Int32.Parse(x));
    
        9
  •  0
  •   Handcraftsman    14 年前
    var numbers = values
        .Where(x => !String.IsNullOrEmpty(x))
        .Where(x => x.All(Char.IsDigit))
        .Select(x => Convert.ToInt32(x))
        .ToArray();