C# 将字符串[]转换为int?[]

C# 将字符串[]转换为int?[],c#,C#,如何将字符串数组转换为可为空的整数数组。通过解析和使用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。然后你可以这

如何将字符串数组转换为可为空的整数数组。

通过解析和使用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();
string[] x = {"15", "10", "hello", "5" };        
int?[] y = Array.ConvertAll(x, TryParseInt32);

那么这两个方面呢,

  • 如何将数组从一种类型转换为另一种类型
  • 如何将字符串转换为可为null的int
第一个很简单-您可以使用,传入一个
转换器
委托。LINQ方法也有(
x.Select(…).ToArray()
),但是如果您知道自己有一个数组要开始,并且希望从另一端1中得到一个数组,那么效率会稍低一些

字符串
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;
    }
}
这样把它们放在一起:

var result = input.Select(ParseNullableInt).ToArray();
string[] x = {"15", "10", "hello", "5" };        
int?[] y = Array.ConvertAll(x, TryParseInt32);

1
Array.ConvertAll
x.Select().ToArray()
更有效,因为它包含更多信息。它可以立即创建最终阵列-无需调整大小。调用
Enumerable.ToArray()
(带有
Select()
)的结果)没有相同的信息,因此它必须有效地将结果添加到
列表中(可能会多次调整大小),然后通常在最后调整大小。(它实际上没有使用
List
,但概念是相同的。)关于Select/ToArray解决方案,绝对值得了解,但我认为在这种情况下,它的可读性实际上并不比
ConvertAll
更高,因此您不妨使用更高效的表单


2您需要在条件中强制转换的原因是编译器不知道您真正指的是什么类型的“null”-但它知道它不能从
null
转换为
int
。条件表达式的类型必须是第二个操作数的类型或第三个操作数的类型,另一个必须是隐式可转换的。通过强制第三个操作数的类型为
int?
,这里一切正常-因为您可以隐式地从
int
转换为
int?
。请注意,编译器不会采用您使用表达式来尝试计算类型的方式。另一种选择是使用
newint?()
而不是
null

编辑:我删除了null/empty检查,因为通过返回false可以正确处理这些情况

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

您需要使用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;
    }
string[]s={“123”、“a”、“45”};
int?[]结果=新int?[s.Length];
对于(int i=0;i
List ints=new List();
foreach(strs中的字符串str)
{
int-val;
if(内锥巴色(str,out val))
{
积分相加(val);
}
else{ints.Add(null);}
}
返回ints.ToArray();
一个选项是(我假设您希望非整数值为空):


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

关于转换

创建长度相同的整数数组或arraylist

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]);
   }
}
int[]\u arr=new int[strArray.length];

对于(int i=0;我不需要LINQ-使用
Array.ConvertAll
来提高性能,而且您可以一直使用它回到.NET 2。@280Z28:提高性能-真的吗?似乎不太可能。此外,我相信这些旧函数在某种程度上被
可枚举的
扩展函数所取代。一致性,等等。真的关于.NET 2。虽然:是的,改进的性能。考虑ToArray在调用选择之后的信息:不是很多。特别是,它不知道如何使数组开始……所以它将从一个小数组开始,然后当它耗尽空间时,它将创建一个新的数组,复制所有现有的值ETC和T。最后是hen trim。将其与Array.ConvertAll进行比较-它确切地知道从多大的数组开始创建数组。用一个大数组和一个小的转换尝试一下,你肯定会看到不同。@Jon:oops,完全忘记了
ToArray
,因为我很少使用它。当然,我想你把结果值弄混了r条件表达式。我应该将null强制转换为(int?)吗?@Ahmed:是的,在第一种情况下强制转换是必要的。@Konrad:是的,我发现了错误,但我的笔记本电脑连接现在很糟糕:(
(int?)null
新int?(
)更有效吗?整数数组不能有null,但可为null的整数数组可以;)
int?[]nullableInts
ftw当你知道你想要一个数组,并且你知道它应该有多大时,为什么要创建一个
列表呢?同样,这正是
array.ConvertAll
的目的。停止重新发明轮子。
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]);
   }
}