views:

134

answers:

7

Hi

I have a string like so:

mystring = "test1, 1, anotherstring, 5, yetanother, 400";

myarray can be of varying length. What I would like to do is split the string up like so:

{"test1, 1"} 
{"anotherstring, 5}
{"yetanother, 400"}

Is this possible? I tried string[] newArray = mystring.Split(',') but that splits it at every comma, and not the second comma which is what I'd like to do.

Thanks for your help

Zaps

+1  A: 

Not with Split alone, but it can certainly be achieved.

I take it that myarray is actually a string, and not an array...?

In that case, you could perhaps do something like this:

string myarray = "test1, 1, anotherstring, 5, yetanother, 400";

string[] sourceArray = myarray.Split(',');
string[] newArray = sourceArray.Select((s,i) =>
   (i % 2 == 0) ? "" : string.Concat(sourceArray[i-1], ",", s).Trim()
).Where(s => !String.IsNullOrEmpty(s)).ToArray();
David Hedlund
apologies - yes myarray is a string. I'll update the question
Zaps
+3  A: 

There is no direct way to make String.Split do this.

If performance is not a concern, you can use LINQ:

var input = "test1, 1, anotherstring, 5, yetanother, 400";

string[] result = input.Split(',');
result = result.Where((s, i) => i % 2 == 0)
               .Zip(result.Where((s, i) => i % 2 == 1), (a, b) => a + ", " + b)
               .ToArray();

Otherwise you'll probably have to split the string manually using String.IndexOf, or using a regular expression.

dtb
+1 because `Zip` is excellent. this will only work in 4.0+ tho.
David Hedlund
+7  A: 

You can use a regular expression to match two items in the string:

string[] parts =
  Regex.Matches(myarray[0], "([^,]*,[^,]*)(?:, |$)")
  .Cast<Match>()
  .Select(m => m.Groups[1].Value)
  .ToArray();

This gets the items from the first string in the array. I don't know why you have the string in an array and if you have more than one string, in that case you have to loop through them and get the items from each string.

Guffa
I like this. I think it's most readable (i.e. no maths) and least prone to off by one bugs etc. +1
spender
A somewhat simpler regular expression is @"\w+,\s+\w+"
Jim Lamb
@Jim: Yes, it works for the specific string in the example, but fails for example with `"test, 1, lost+found, 2"` or `"test, 1, , 2"`.
Guffa
Possibly, although it means that values with non-word chars, spaces, empty values and the like will not make it through. Guffa's regex allows everything except commas, which is better IMO.
spender
Actually @guffa, you are selecting the entire match which includes a trailing comma. Better to .Select(m=>m.Groups[1].Value) instead.
spender
@spender: Yes, you are right. That's what I usually do, I missed it this time.
Guffa
+1  A: 

You could probably use a Regular Expression on the original string to replace every other comma with a different 'token', e.g. ';' Then just call string.split on the new token instead.

barrylloyd
+1  A: 

Another LINQ-based solution here. (Perhaps not the most efficient, but it allows for concise code and works for grouping into arbitrary group sizes).


1) Define a new query operator, InGroupsOf:

public static IEnumerable<T[]> InGroupsOf<T>(this IEnumerable<T> parts,
                                             int groupSize)
{
    IEnumerable<T> partsLeft = parts;
    while (partsLeft.Count() >= groupSize)
    {
        yield return partsLeft.Take(groupSize).ToArray<T>();
        partsLeft = partsLeft.Skip(groupSize);
    }
}

2) Second, apply it to your input:

// define your input string:
string input = "test1, 1, anotherstring, 5, yetanother, 400";

// split it, remove excessive whitespace from all parts, and group them together:
IEnumerable<string[]> pairedInput = input
                                    .Split(',')
                                    .Select(part => part.Trim())
                                    .InGroupsOf(2);  // <-- used here!

// see if it worked:
foreach (string[] pair in pairedInput)
{
    Console.WriteLine(string.Join(", ", pair));
}
stakx
A: 

Interesting question... I'd do it like this:

string input = "test1, 1, anotherstring, 5, yetanother, 400";
string pattern = @"([^,]*,[^,]*),";

string[] substrings = Regex.Split(input, pattern).Where(s => s!="").Select(s => s.Trim()).ToArray();

You get exactly what you want. Only its dirty... =P =)

Cipi
A: 

using IEnumerator..

       var myarray = "test1, 1, anotherstring, 5, yetanother, 400";
       System.Collections.IEnumerator iEN = myarray.Split(',').GetEnumerator();
       var strList = new List<string>();
       while (iEN.MoveNext())
       {
           var first = iEN.Current;
           iEN.MoveNext();
           strList.Add((string)first + "," + (string)iEN.Current);
       }

:)

Cheers

Ramesh Vel