locked
Cumbersome Split RRS feed

  • Question

  • The Split method requires an array passed in:

    string[] at = { "@" };
    string[] ats = s.Split(at, StringSplitOptions.None);

    Is there a way to do this "in line" without declaring an otherwise useless variable?
    I tried this:
    string[] ats = s.Split({"@"}, StringSplitOptions.None);
    but that did not compile.

    Thanks,
    Jon

    Friday, September 18, 2009 2:13 PM

Answers

  • Just create the object in the line itself (however, the object will still be created, the only difference is that the reference is not stored into a local variable.

    string[] ats = s.Split(new string[] {"@"}, StringSplitOptions.None);

    Geert van Horrik - CatenaLogic
    Visit my blog: http://blog.catenalogic.com

    Looking for a way to deploy your updates to all your clients? Try Updater!
    • Marked as answer by Jon Q Jacobs Friday, September 18, 2009 7:09 PM
    Friday, September 18, 2009 2:26 PM

All replies

  • Just create the object in the line itself (however, the object will still be created, the only difference is that the reference is not stored into a local variable.

    string[] ats = s.Split(new string[] {"@"}, StringSplitOptions.None);

    Geert van Horrik - CatenaLogic
    Visit my blog: http://blog.catenalogic.com

    Looking for a way to deploy your updates to all your clients? Try Updater!
    • Marked as answer by Jon Q Jacobs Friday, September 18, 2009 7:09 PM
    Friday, September 18, 2009 2:26 PM
  • I should also point out that you only need to use the array variant if you need to specify additional options or a limit count.  For just splitting on a set of characters you can do this:

    string[] ats = s.Split('@', ':', '/');

    Michael Taylor - 9/18/09
    http://p3net.mvps.org
    Friday, September 18, 2009 2:32 PM
  • What also works but not the nicest looking piece of code is

    string[] ats = s.Split("@".ToCharArray(), StringSplitOptions.None);
    Friday, September 18, 2009 2:34 PM
  • It's a bit silly that Microsoft didn't give us an overload that puts the params array at the end, then you could use that with a StringSplitOptions.

    If you really want, you could add your own extensions like so:

    using System;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main()
            {
                string s = "lkj,asln;kjd,sdfa;sadas,whjh,akjask;akj;kja";
    
                foreach (string item in s.Split(StringSplitOptions.None, ',', ';'))
                {
                    Console.WriteLine(item);
                }
    
                Console.WriteLine("---------------------------");
    
                foreach (string item in s.Split(5, StringSplitOptions.None, ',', ';'))
                {
                    Console.WriteLine(item);
                }
            }
        }
    
        public static class StringExt
        {
            public static string[] Split(this string s, StringSplitOptions opts, params char[] seps)
            {
                return s.Split(seps, opts);
            }
    
            public static string[] Split(this string s, int count, StringSplitOptions opts, params char[] seps)
            {
                return s.Split(seps, count, opts);
            }
        }
    }
    
    Friday, September 18, 2009 2:57 PM
  • While I would, in general, agree there are a few mitigating circumstances here.  Firstly the StringSplitOptions stuff was added in v2.0.  So the only original methods were (params char[]) and (char[], int). 

    The second issue is that one of the design guidelines (that is highly recommended) is that overloads do not change the order of parameters.  When adding overloads you should always put the less frequently used parameters last.  This helps cut down on confusion and makes it easier to switch to other overloads when needed.  Since the only thing you really need to do a split is the delimiter(s) it should get first dibs since next most common parameter (the starting index) wouldn't be needed in all cases.  It would be confusing to have this order:

    Split(params char[] delims);
    Split(int startingIndex, params char[] delims);

    Anybody who has to use Intellisense or MSDN to remember if the parameter name comes before or after the error message in the various ArgumentException ctors can vouche for consistency.

    I do like the extension method approach but not as part of the core framework.  Two methods that do the same thing but with different parameter orders adds little to the library except confusion.  It makes you wonder why there are two different methods that accept the same inputs. 

    Personally my only gripe is with the verbose way we have to define arrays.  Given the advances in dynamic language support I wouldn't mind seeing a language extension (as much as I loathe them) that provides us a shorthand for inlining arrays.  Something like this would be nice:

    str.Split({'@', ':'}, 4);

    The compiler ultimately converts varargs to arrays anyway so the only extra step is for the compiler to confirm that the array we give it is valid for the context but it has to do that anyway.  Of course there are cases where the compiler won't be able to figure out the correct type but in the common case it could.  The only downside to this approach is that it looks eerily like lambda expressions.  IMHO.

    Michael Taylor - 9/18/09
    http://p3net.mvps.org
    Friday, September 18, 2009 3:13 PM
  • That looks good! I didn't know about that form. It does not show up in intellisense.
    Friday, September 18, 2009 7:10 PM
  • Looks good to me. I like it.
    Friday, September 18, 2009 7:12 PM
  • That's the kind of syntax I tried in the first place, so I heartily endorse the extension (as if that made any difference <g>).
    Friday, September 18, 2009 7:17 PM
  • You nailed it! Thanks.
    >difference is that the reference is not stored into a local variable.
    True, but even literal parameters passed wind up that way eventually.
    My attempted syntax would have been the same as what you gave as the answer (if it had been valid).

    >string[] ats = s.Split(new string[] {"@"}, StringSplitOptions.None);
    I should have thought of what you gave. I must have had a mental block.

    Much appreciated.
    Friday, September 18, 2009 7:23 PM
  • Great thread guys.  I was frustrated with Split and just knew there had to be a better way to use.  One search on Split and this was exactly the question I was going to ask but with great suggestions already supplied!
    Sunday, September 27, 2009 5:18 PM