Matthew
Matthew

Reputation: 29206

In LINQ, can I select multiple items?

Say I have an array of strings like this:

string [] foos = {
    "abc",
    "def",
    "ghi"
};

I want a new collection that contains each string and its reverse. So the result should be:

    "abc",
    "cba",
    "def",
    "fed",
    "ghi",
    "ihg"

I could just iterate through the array, but this is pretty clumsy:

string Reverse (string str)
{
    return new string (str.Reverse ().ToArray ());
}

List<string> results = new List<string> ();
foreach (string foo in foos) {
    results.Add (foo);
    results.Add (Reverse(str));
}

Is there a way to do this in LINQ? Something like

var results = from foo in foos
    select foo /* and also */ select Reverse(foo)

Upvotes: 6

Views: 4320

Answers (2)

Aussie Craig
Aussie Craig

Reputation: 772

I think what your after is the following:

    static void Main(string[] args)
    {
        string[] foos = { "abc", "def", "ghi" }; 
        string[] result = foos.Union(foos.Select(A=> new string(A.ToCharArray().Reverse().ToArray()))).ToArray();
        foreach(string a in result) Debug.WriteLine(a);
    }

The "tricks":

  • Use the union to result in one sequence.
  • Convert the string to a Char[], and reverse that sequence
  • Use the string constructor which takes a char[] to build a new string for the sequence

Upvotes: 0

dtb
dtb

Reputation: 217253

var result = from foo in foos
             from x in new string[] { foo, Reverse(foo) }
             select x;

or

var result = foos.SelectMany(foo => new string[] { foo, Reverse(foo) });

This maps each foo in foos to an array which consists of two elements: foo and Reverse(foo). Then it concatenates all these two-element arrays into a single, large enumerable.

{                           {                             {
"abc",                          {
                                "abc",                    "abc",
                                "cba",                    "cba",
                                },
"def",           =>             {              =>
                                "def",                    "def",
                                "fed",                    "fed",
                                }
"ghi",                          {
                                "ghi",                    "ghi",
                                "ihg",                    "ihg",
                                }
}                           }                             }

If the order of your output is not so important, you can also concatenate the original array with the result of mapping each element in the original array using the Reverse method:

var result = foos.Concat(from foo in foos select Reverse(foo));

or

var result = foos.Concat(foos.Select(Reverse));
{                               {                               {
"abc",                          "abc",                          "abc",
"def",           =>             "def",           =>             "def",
"ghi",                          "ghi",                          "ghi",
}                               }
                                concat
                                {
                                "cba",                          "cba",
                                "fed",                          "fed",
                                "ihg",                          "ihg",
                                }                               }

Upvotes: 14

Related Questions