将字符串数组转换为整型数组?

3
如何将字符串数组转换为可空整数数组。
7个回答

10

好的,两个方面是:

  • 如何将一个数组从一种类型转换为另一种类型?
  • 如何将字符串转换为可空int?

第一个问题很简单 - 您可以使用 Array.ConvertAll,传入一个Converter委托。当然也有LINQ的方式 (x.Select(...).ToArray()),但如果您知道您已经有一个数组并且希望在另一端得到一个数组,则这种方法略微效率低下1

string转换为int?最好在一个方法中完成。虽然您可以在匿名函数中执行此操作,但在这种特定情况下,我会使用单独的方法。我很少喜欢在匿名函数中声明变量。

public static int? TryParseInt32(string text)
{
    int value;
    return int.TryParse(text, out value) ? value : (int?) null;
}
回答该评论,是的,你需要进行类型转换2
或者不使用条件语句:
public static int? TryParseInt32(string text)
{
    int value;
    if (int.TryParse(text, out value))
    {
        return value;
    }
    else
    {
        return null;
    }
}

像这样把它们放在一起:

string[] x = {"15", "10", "hello", "5" };        
int?[] y = Array.ConvertAll(x, TryParseInt32);

1 Array.ConvertAllx.Select().ToArray()更高效,因为它拥有更多的信息。它可以立即创建最终数组 - 从未需要调整大小。调用Select()的结果,再调用Enumerable.ToArray()时不具备相同的信息,所以实际上必须将结果添加到List<T>中(可能会多次调整大小),然后在最后通常也要调整大小。虽然值得了解Select/ToArray的解决方案,但在这种情况下,我不认为它比ConvertAll更易读,所以你应该使用更高效的形式。

2 在条件语句中需要强制转换类型是因为编译器不知道你真正意味着哪种类型的“null”-但它知道无法将null转换为int。条件表达式的类型必须是第二个操作数的类型或第三个操作数的类型之一,并且另一个类型必须是隐含可转换的。在此强制第三个操作数的类型为int?,则一切都正常,因为你可以隐式地从int转换为int?。请注意,编译器不会根据你使用表达式的方式来尝试解析类型。另一种方法是使用new int?()代替null


我认为你在条件表达式中混淆了结果值。 - Konrad Rudolph
我需要将 null 强制转换为 (int?) 吗? - Ahmed
@Ahmed:是的,在第一种情况下强制类型转换是必要的。 - Konrad Rudolph
@Konrad:是的,我发现了这个错误,但是我的笔记本连接现在很差 :( - Jon Skeet
(int?) nullnew int?()更有效率吗? - cdmckay
@cdmckay:它们完全等价。它们将编译为相同的代码。 - Jon Skeet

5

通过解析和使用Linq:

string[] input = { "1", "3", "x" }
var result = input.Select(
    s => { int i; return (int.TryParse(s, out i)) ? i : (int?) null; }).ToArray();

...但我承认这有点晦涩。我不会在这里使用lambda表达式。为了清晰起见,这应该属于一个适当的函数ParseNullableInt。然后您可以像这样调用它:

var result = input.Select(ParseNullableInt).ToArray();

不需要使用LINQ - 使用Array.ConvertAll可以提高性能,而且你可以在.NET 2中使用它。 - Sam Harwell
@280Z28:性能提升了?真的吗?此外,我认为这些旧函数在某种程度上已被“Enumerable”扩展函数所取代。一致性,诸如此类。不过,在.NET 2.0中确实是这样的。 - Konrad Rudolph
5
@Konrad: 是的,改善性能。考虑一下在调用Select后,ToArray所具有的信息:并不多。特别是它 不知道起始时应该制作多大的数组......所以它将从一个小数组开始,然后当它的空间用尽时,它会创建一个新数组,复制所有现有值等-然后在最后进行修剪。与Array.ConvertAll相比较-它知道起始时应该制作多大的数组。尝试使用大数组和微不足道的转换,你肯定会看到差异。 - Jon Skeet
@Jon:糟糕,我完全忘记了 ToArray,因为我很少使用它。对,当然。 - Konrad Rudolph

5

编辑:我删除了空值/空检查,因为TryParse会正确处理这些情况并返回false。


string[] stringArray = ...;
int?[] nullableIntArray = Array.ConvertAll(stringArray,
    s =>
    {
        int value;
        if (!int.TryParse(s, out value))
            return default(int?);
        return (int?)value;
    });

2
一种选择是这样的(我假设您希望将非整数值设置为 null):
public static class StringArrayExtension
{
    public static int?[] ToNullableIntArray(this string[] array)
    {
        int?[] result = new int?[array.Length];
        for (int index = 0; index < array.Length; index++)
        {
            string sourceValue = array[index];
            int destinationValue;
            if (int.TryParse(sourceValue, out destinationValue))
            {
                result[index] = destinationValue;
            }
            else
            {
                result[index] = null;
            }
        }
        return result;
    }
}

使用方法:

string[] source = { "hello", "1", "3.1415", "20", "foo" };
int?[] dest = source.ToNullableIntArray();

1
为什么在你知道最终需要一个数组,而且你确切地知道它应该有多大时还要创建一个List<T>呢? - Jon Skeet
这正是 Array.ConvertAll 的用途。别再重复造轮子了。 - Sam Harwell

0
你需要使用 int.TryParse:
    string[] s = { "123", "a", "45" };
    int?[] result = new int?[s.Length];
    for (int i = 0; i < s.Length; ++i)
    {
        int a;
        if (int.TryParse(s[i], out a))
            result[i] = a;
    }

0
List<int?> ints = new List<int?>();
foreach (string str in strs)
{
    int val;
    if (int.TryParse(str, out val))
    {
        ints.Add(val);
    }
    else { ints.Add(null); }
}
return ints.ToArray();

-2

整数数组不能为空。事实上,整数数组中的每个元素默认都为“0”。

关于转换

创建一个相同长度的整数数组或数组列表

int [] _arr=new int[strArray.length];
for(int i=0;i<strArray.length;i++]
{
   if(String.IsNullOrEmpty(strArray[i]))
   {
       _arr[i]=0;
   }
   else
   {
       _arr[i]=int.Parse(strArray[i]);
   }
}

一个整数数组不能为null,但是可空整数数组可以;) int?[] nullableInts FTW - tster

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接