开发者

String Split Utility Method Problem when No delimiters are included

I've got the following method I created which works fine if there actually is the delimiter in question. I want to keep this out of LINQ for now...

e.g.

If I pass in the string "123;322;323" it works great.

But if I only pass in one string value without the delimiter such as "123" it obviously is not going to split it since there is no delimiter. I am just trying to figure out the best way to check and account for this and be able to spit out that one value back in the list

public static List<int> StringToList(string st开发者_JAVA百科ringToSplit, 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;
}

UPDATED: This is what I came up with that seems to work but sure is long

    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;
    }


Change this condition:

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

To:

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

This works because String.Split will return the original string if it can't find the delimiter:

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


There are a LOT of unnecessary checks for conditions that don't matter to the core logic of the method.

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; 
}

Try this. You hopefully have some unit tests calling this method to make sure it works...right?

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;
}


Personally, I haven't tried out your code, but it looks functional. The Split method should return an array with one element.

Since you say it's not, I believe you, and I would add this to the top of your method:

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


You don't need to account for that situation, as string.Split() returns an array with a single element when no delimiter is found:

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

See msdn at "Remarks"


Might I suggest an extension method to help you in cases like this in general?

The idea would be to yield return all results from a collection of strings that can be parsed to a specified type.

First you'd need a delegate to match the signature of your standard TryParse method:

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

Then you can write an extension method that takes an instance of this delegate type and enumerates over a collection of strings, parsing everywhere it can:

// 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;
        }
    }
}

Now your StringToList method becomes trivial to implement:

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();
}


A shorter implementation you might consider.

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();
}


Either it must have a delimiter or, it part must have a fixed length or, the string must follow a pattern for repeat behavior.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜