Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using C# , LINQ how to pick items between markers again and again?

Tags:

c#

linq

Say I have an array of strings:

string[] strArray = {"aa", "bb", "xx", "cc", "xx", "dd", "ee", "ff", "xx","xx","gg","xx"};

How do I use LINQ to extract the strings between the "xx" markers as groups?

Say by writing them to the console as:

cc
dd,ee,ff
gg
like image 328
David Smith Avatar asked May 01 '09 22:05

David Smith


People also ask

What is using () in C#?

The using statement causes the object itself to go out of scope as soon as Dispose is called. Within the using block, the object is read-only and can't be modified or reassigned. A variable declared with a using declaration is read-only.

Is Vs as C#?

The is operator returns true if the given object is of the same type, whereas the as operator returns the object when they are compatible with the given type. The is operator returns false if the given object is not of the same type, whereas the as operator returns null if the conversion is not possible.

Does using statement Call dispose?

The using statement guarantees that the object is disposed in the event an exception is thrown. It's the equivalent of calling dispose in a finally block.

What is the use of in front of a variable in C#?

What is the @ symbol in front of variables in C#? From the C# documentation it states that the @ symbol is an Identifier. The prefix “@” enables the use of keywords as identifiers, which is useful when interfacing with other programming languages.


1 Answers

A pure-functional solution (mutation-free):

string[] strArray = { "aa", "bb", "xx", "cc", "xx", "dd", 
                      "ee", "ff", "xx", "xx", "gg", "xx" };

var result = 
 strArray.Aggregate((IEnumerable<IEnumerable<string>>)new IEnumerable<string>[0],
   (a, s) => s == "xx" ? a.Concat(new[] { new string[0] })
      : a.Any() ? a.Except(new[] { a.Last() })
                   .Concat(new[] { a.Last().Concat(new[] { s }) }) : a)
         .Where(l => l.Any());

// Test
foreach (var i in result)
  Console.WriteLine(String.Join(",", i.ToArray()));

If you want to filter out the results past the last marker:

string[] strArray = { "aa", "bb", "xx", "cc", "xx", "dd", 
                      "ee", "ff", "xx", "xx", "gg", "xx"};

var result = 
  strArray.Aggregate(
    new { C = (IEnumerable<string>)null, 
          L = (IEnumerable<IEnumerable<string>>)new IEnumerable<string>[0] },
    (a, s) => s == "xx" ? a.C == null
        ? new { C = new string[0].AsEnumerable(), a.L }
        : new { C = new string[0].AsEnumerable(), L = a.L.Concat(new[] { a.C }) } 
        : a.C == null ? a : new { C = a.C.Concat(new[] { s }), a.L }).L
          .Where(l => l.Any());

// Test
foreach (var i in result)
  Console.WriteLine(String.Join(",", i.ToArray()));
like image 95
mmx Avatar answered Oct 10 '22 17:10

mmx