字符串拆分实用程序方法包含无分隔符时出现问题

时间:2010-06-29 13:15:45

标签: c#

我已经创建了以下方法,如果实际存在有问题的分隔符,则该方法可以正常工作。我想暂时不使用LINQ ......

e.g。

如果我传入字符串“123; 322; 323”,它的效果很好。

但是如果我只输入一个没有分隔符的字符串值,例如“123”,那么显然不会拆分它,因为没有分隔符。我只想弄清楚检查和解决这个问题的最佳方法,并能够在列表中吐出一个值

public static List<int> StringToList(string stringToSplit, char splitDelimiter)
{
    List<int> list = new List<int>();

    if (string.IsNullOrEmpty(stringToSplit))
        return list;

    string[] values = stringToSplit.Split(splitDelimiter);

    if (values.Length < 1)
        return list;

    foreach (string s in values)
    {
        int i;
        if (Int32.TryParse(s, out i))
            list.Add(i);
    }

    return list;
}

更新:这是我提出的似乎有用但确实很长的

    public static List<int> StringToList(string stringToSplit, char splitDelimiter)
    {
        List<int> list = new IntList();

        if (string.IsNullOrEmpty(stringToSplit))
            return list;

        if (stringToSplit.Contains(splitDelimiter.ToString()))
        {
            string[] values = stringToSplit.Split(splitDelimiter);

            if (values.Length <= 1)
                return list;

            foreach (string s in values)
            {
                int i;
                if (Int32.TryParse(s, out i))
                    list.Add(i);
            }
        }
        else if (stringToSplit.Length > 0)
        {
            int i;
            if(Int32.TryParse(stringToSplit, out i))
                list.Add(i);
        }

        return list;
    }

7 个答案:

答案 0 :(得分:6)

更改此条件:

if (values.Length <= 1)
    return list;

要:

if (values.Length <= 0)
    return list;

这是有效的,因为String.Split如果找不到分隔符,将返回原始字符串:

// stringToSplit does not contain the splitDelimiter
string[] values = stringToSplit.Split(splitDelimiter);
// values is a string array containing one value - stringToSplit

答案 1 :(得分:2)

对于与方法的核心逻辑无关的条件,有很多不必要的检查。

public static List<int> StringToList(string stringToSplit, char splitDelimiter) 
{ 
    List<int> list = new IntList(); 

    if (string.IsNullOrEmpty(stringToSplit)) 
        return list; 

    //this if is not necessary. As others have said, Split will return a string[1] with the original string if no delimiter is found
    if (stringToSplit.Contains(splitDelimiter.ToString())) 
    { 
        string[] values = stringToSplit.Split(splitDelimiter); 

        //why check this? if there are no values, the foreach will do nothing and fall through to a return anyway.
        if (values.Length <= 1) 
            return list; 

        foreach (string s in values) 
        { 
            int i; 
            if (Int32.TryParse(s, out i)) 
                list.Add(i); 
        } 
    } 
    //again, this is rendered redundant due to previous comments
    else if (stringToSplit.Length > 0) 
    { 
        int i; 
        if(Int32.TryParse(stringToSplit, out i)) 
            list.Add(i); 
    } 

    return list; 
}

试试这个。您希望有一些单元测试调用此方法以确保它正常工作......对吗?

public static List<int> StringToList(string stringToSplit, char splitDelimiter) 
{ 
    List<int> list = new IntList(); 

    if (string.IsNullOrEmpty(stringToSplit)) 
        return list;

    foreach(var s in stringToSplit.Split(splitDelimiter))
    {
        int i;
        if(int.TryParse(s, out i))
            list.Add(i);
    }
    return list;
}

答案 2 :(得分:1)

就个人而言,我还没有尝试过您的代码,但它看起来很实用。 Split方法应返回一个包含一个元素的数组。

既然你说它不是,我相信你,我会把它添加到你的方法的顶部:

if (!stringToSplit.Contains(splitDelimiter))
{
    int i;
    if (Int32.TryParse(stringToSplit, out i))
        list.Add(i);
    return list;
}

答案 3 :(得分:1)

您不需要考虑这种情况,因为string.Split()在没有找到分隔符的情况下返回一个包含单个元素的数组:

If this instance does not contain any of the strings in separator, the returned array consists of a single element that contains this instance.

请参阅“备注”中的msdn

答案 4 :(得分:1)

我可以建议一种扩展方法来帮助你处理这种情况吗?

我们的想法是yield return来自可以解析为指定类型的字符串集合的所有结果。

首先,您需要一个代理来匹配标准TryParse方法的签名:

public delegate bool Parser<T>(string input, out T value);

然后你可以编写一个扩展方法,它接受一个这个委托类型的实例,并枚举一个字符串集合,解析它可以在任何地方:

// Notice: extension methods must belong to a class marked static.
public static class EnumerableParser
{
    // modified code to prevent horizontal overflow
    public static IEnumerable<T> ParseAll<T>
    (this IEnumerable<string> strings, Parser<T> parser)
    {
        foreach (string str in strings)
        {
            T value;
            if (parser(str, out value))
                yield return value;
        }
    }
}

现在,您的StringToList方法变得微不足道了:

public List<int> StringToList(string stringToSplit, char delimiter)
{
    // Notice: since string.Split returns a string[], and string[] implements
    // IEnumerable<string>, so the ParseAll extension method can be called on it.
    return stringToSplit.Split(delimiter).ParseAll<int>(int.TryParse).ToList();
}

答案 5 :(得分:0)

您可能会考虑更短的实施。

public static List<int> StringToList(string stringToSplit, char splitDelimiter)
{
    int i;
    return stringToSplit.Split(splitDelimiter)
        .Where(str => int.TryParse(str, out i))
        .Select(str => int.Parse(str))
        .ToList();
}

答案 6 :(得分:0)

它必须具有分隔符,或者它必须具有固定长度,或者字符串必须遵循模式才能重复行为