在C#中将List<string>转换为List<int>

24

我想把一个 List<string> 转成 List<int>

这是我的代码:

void Convert(List<string> stringList)
{
    List<int> intList = new List<int>();  
    for (int i = 0; i < stringList.Count; i++) 
    {  
        intList.Add(int.Parse(stringList[i]));  
    }
)

请参考 https://dev59.com/x3VC5IYBdhLWcg3wvTxa#199484。 - Stefan
你应该以某种方式保留 intList。将 void 改为 intList 并返回 intList 是很自然的。 - Jeppe Stig Nielsen
@user2939293 你是C#的初学者吗? - Vishal Sharma
@user2939293,你下面有很多答案,每个人都尽力了。你应该接受一个符合你要求的答案。 - tariq
是的,我在C#方面是一个相当新的初学者。 - user2939293
1
可能是重复的问题:如何将List<string>转换为List<int>? - Niklas
8个回答

48

我尝试了这个,但出现了System.FormatException错误:'输入字符串的格式不正确。' - Goblinkiller
在这种情况下,列表中至少有一个字符串无法转换为int。它可能是一个虚假的值,比如“one”或string.Empty。也可能是当前系统文化不能用于解析该字符串,在这种情况下,您应该传递一个文化参数 - heijp06

15
我建议使用TryParse(),以防一些值无法转换为int。 为此,我创建了一个扩展方法。以下是我的演示LinqPad代码。
void Main()
{
    List<string> sourceList = new List<string> {"1", "2","3", "qwert","4", "5","6", "7","asdf", "9","100", "22"};
    //Dump is a LinqPad only method. Please ignore
    sourceList.ConvertToInt().Dump();
}

static public class HelperMethods
{
    static public List<int> ConvertToInt(this List<string> stringList)
    {
        int x = 0;
        var intList = stringList.Where(str => int.TryParse(str, out x))
                                .Select (str => x)
                                .ToList();
        return intList;

    }
}

在这种情况下,只有数值类型的整数值被解析,其余部分会被优雅地忽略。如果您想要,您可以内置一些错误处理/通知。 根据Peter Kiss'的建议,在此基础上提供了一种更通用的方法,基于IEnumerable接口实现。
static public IEnumerable<int> ConvertToInt(this IEnumerable<string> source)
{
    int x = 0;
    var result = source.Where(str => int.TryParse(str, out x))
                        .Select (str => x);

    return result;      
}

使用这种方法,您只需在调用ConvertToInt()之前调用AsEnumerable()。结果当然是IEnumerable<Int32>类型,从这里开始,您可以通过使用.ToList()将其轻松转换为列表或数组,或者在该点上需要什么。

他是初学者,你为什么要用扩展方法、LINQ等来让他困惑呢? - Vishal Sharma
1
这个答案不仅适用于OP。其他用户可能会在某一天搜索答案并多次重复使用它。因此,需要一个扩展方法。我已删除我的初始评论,因为我认为它不合适。我认为这样表述更好。 - Marco
在这种情况下,逆变性介绍对所有人也将非常有帮助.. http://msdn.microsoft.com/en-us/library/vstudio/ee207183.aspx - Vishal Sharma
我喜欢这个解决方案,但作为扩展方法,你应该使用更通用的签名:将IEnumerable<string>作为输入,将IEnumerable<int>作为返回类型。 - Peter Kiss
非常好的观点,我自由地将其编辑到我的帖子中作为另一种方法。 - Marco
显示剩余2条评论

5
使用 Linq:
var intList = stringList.Select(x => int.Parse(x)).ToList();

3
由于lambda箭头=>左侧的参数列表与Parse方法的参数列表相同,因此可以简化为... .Select(int.Parse). ... - Jeppe Stig Nielsen
@Peter Kiss,这可能会抛出常见的异常:“输入字符串格式不正确”。 - tariq
当然,但也许这不是个问题。谁知道呢?也许问题就在于使用一些虚假的返回值(如int.TryParse之后的-1)来隐藏异常? - Peter Kiss

3
请使用以下代码:
int x = 0;

var intList= stringList.Where(str => int.TryParse(str, out x)).Select(str => x).ToList();

1
如果您不想使用 Linq(我总是觉得很难理解),那么您的代码看起来没问题,但当然您需要返回一些内容:
List<int> Convert(List<string> stringList)
{
    List<int> intList = new List<int>();  

    for (int i = 0; i < stringList.Count; i++) 
    {  
        intList.Add(int.Parse(stringList[i]));  
    }
    return intList;
}

请注意,如果字符串列表中包含无法解析为整数的内容,这将引发异常。 编辑: 更好的方法是使用foreach循环:
List<int> Convert(List<string> stringList)
{
    List<int> intList = new List<int>();  

    foreach(String s in stringList) 
    {  
        intList.Add(int.Parse(s));  
    }
    return intList;
}

这很好,但在这种情况下使用foreach而不是for是很自然的。或者使用Linq,就像你所写的那样。 - Jeppe Stig Nielsen
如果使用新的List<T>实例来从另一个已经在内存中的集合转换项,则使用它的Count()或Length来创建新的List以指定其大小。对于大型集合,总是为新列表中的项分配更多空间可能会导致性能问题(new List<T>只会有一个空数组)。 - Peter Kiss
谢谢,我会使用foreach。 - user2939293
我认为Linq更难,因此我更喜欢使用其他东西。 - user2939293

1

非常感谢大家,这里提供的帮助真是太棒了! 我最终通过将字符串列表转换为数组,然后将数组转换为整数来解决了问题。也许不是最明智的解决方案,但我的代码现在正常工作。稍后我将尝试您的建议,看看是否仍然可以使用列表而不是数组。 再次感谢大家!


0
你的方法很好,所以我假设你是一位初学者开发人员,仍在学习语言的语法。我暂时不会给你高级的LINQ解决方案,但会帮助你使用当前的代码实现你想要的功能。你目前没有返回你创建的列表,所以请将方法签名改为:
void Convert(List<string> stringList)

to:

List<int> Convert(List<string> stringList)

在方法结束之前,添加以下内容:

return intList;

然后在你的代码中,你可以这样调用它:

List<string> strings = new List<string> { "1", "2", "3" };
List<int> integers = this.Convert(strings);

注意:如果您不希望代码抛出异常,我建议使用TryParse而不是Parse,但要小心,因为这种方法的工作方式略有不同,并且使用了out参数。您可以在此处了解更多信息。

如果您对LINQ感兴趣,@Peter Kiss的解决方案是最好的。他使用方法语法与LINQ一起使用,但也有类似SQL的语法,您可能会发现它更容易理解。关于LINQ的良好介绍可以在此处找到。


是的,我是一个初学者。我不想返回列表。我想稍后在方法中对其进行操作,因此我使用void。 我已经尝试过List<int> integers = this.Convert(strings); 但它不起作用。但还是谢谢你的帮助。 - user2939293

-1
如果您的stringList中有一个无法解析的字符串,那么您可以使用默认的错误/无效值(例如-1)来掩盖它,而不是像下面那样遇到异常:
        List<string> stringList = new List<string>();
        stringList.AddRange(new string[] { "1", "2", "3", "4", "sdfsf", "7" }); // for illustration
        int temp;
        var yourIntegerList = stringList.Select(x => int.TryParse(x, out temp) ? int.Parse(x) : -1).ToList(); // -1 used here, can be any integer

// 现在你可以移除所有的 -1

        yourIntegerList = yourIntegerList.Where(a => a != -1).ToList();

两次解析可能会导致性能问题,而-1可能会隐藏输入列表中的错误,并且如果输入本身包含值为“-1”的字符串,则可能会产生无效结果。 - Peter Kiss
@PeterKiss,我们都缺少一些东西,不是吗? :D - tariq
也许对于这样简单的问题,没有完美的解决方案?:D - Peter Kiss

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