3

I'm finding it hard to explain this question, but I think it's a common problem many of us have come across.

Assume I have a List<string, string> in the following format:

1, value-
1, and value-
1, again value-
2, another value-
2, yet another value-

I'd like to convert this into List<string> which would have only contain 2 items

value-and value-again value-
another value-yet another value

This is based upon the number (1 or 2).

The code I typically use works, but seems some what cumbersome.

Is there a neater way, possibly with Linq?

A quick console app to demonstrate what I'm trying to do which hopefully explains it better than my question!

class Program
{
    static void Main(string[] args)
    {
        List<Tuple<string, string>> myTuple = new List<Tuple<string, string>>();
        myTuple.Add(new Tuple<string, string>("1", "value-"));
        myTuple.Add(new Tuple<string, string>("1", "and value-"));
        myTuple.Add(new Tuple<string, string>("1", "again value-"));
        myTuple.Add(new Tuple<string, string>("2", "another value-"));
        myTuple.Add(new Tuple<string, string>("2", "yet another value"));

        string previousValue = "";
        string concatString = "";
        List<string> result = new List<string>();
        foreach (var item in myTuple)
        {
            if (string.IsNullOrEmpty(previousValue)) 
                previousValue += item.Item1;

            if (previousValue == item.Item1)
                concatString += item.Item2;
            else
            {
                result.Add(concatString);
                concatString = "";
                previousValue = item.Item1;
                concatString=item.Item2;
            }
        }
        //add the last value
        result.Add(concatString);
    }
Dave
  • 8,163
  • 11
  • 67
  • 103
  • possible duplicate of [Group by in LINQ](http://stackoverflow.com/questions/7325278/group-by-in-linq) – asawyer Feb 27 '14 at 14:24

1 Answers1

7
List<string> result = myTuple.GroupBy(t => t.Item1)
                     .Select(g => String.Join(" ", g.Select(tp=>tp.Item2)))
                     .ToList();
L.B
  • 114,136
  • 19
  • 178
  • 224
  • 4
    No, this will take identical items no matter in what order they come. OP's code is very particular about them coming in consecutive order. – Sergey Kalinichenko Feb 27 '14 at 14:27
  • Replace `" "` with `string.Empty` to get the expected result. – Jay Feb 27 '14 at 14:27
  • @DaveRook This will not produce the same result if your values are `1,2,1,2`: your code will make five groups, because identical items are not consecutive, while the code above will make two, because it does not need identical values to be consecutive. – Sergey Kalinichenko Feb 27 '14 at 14:29
  • @dasblinkenlight, You're right.. however, my question doesn't ask that sadly (although it IS something I will need)... I think I need to ask a new question as L.B's answer does answer my question as it stands... – Dave Feb 27 '14 at 14:32
  • @DaveRook Try re-ordering the tuples in your example, and compare outputs of this code snippet and yours. – Sergey Kalinichenko Feb 27 '14 at 14:32
  • @DaveRook I think the title of your question says it all -- "a value is same as previous value" – Sergey Kalinichenko Feb 27 '14 at 14:33
  • yep, after re-ordering the items this will not work... but question is not clear if the items are ordered or not – Arsen Mkrtchyan Feb 27 '14 at 14:36
  • Sorry all about the confusion, I tried to write a simple question to avoid confusion and look what happened :( – Dave Feb 27 '14 at 14:37
  • no @DaveRook, OrderBy will not work, it still give the same result as in this example – Arsen Mkrtchyan Feb 27 '14 at 14:37
  • Ah, I see. I can work with it like this, the order isn't strict as long as the grouping is correct. Thank you everyone for the extra comments and help. – Dave Feb 27 '14 at 14:39