0

Im having an empty dictionary:

Dictionary<List<string>, int> occurrences = new Dictionary<List<string>, int>();

And this is my jagged list:

List<List<string>> jaggedList = new List<List<string>>();

And x is the number of first elements that i was about to count in the jagged list. In this example:

x=2;

But i want it to change it myself whenever i get a "thicker" sublists than x+1

Jagged list:

{ cc kk ww }
{ cc kk aa }
{ cc oo ll }
{ cc jj oo }
{ ww oo kk }
{ ww oo gg }
{ ww gg kk }
{ kk ll oo }
{ ll kk nn }
{ mm nn oo }
{ mm nn jj }

I am completely hopeless with LINQ so i can not do it myself. I want my occurrences dictionary to get grouped x indexed elements in TKeyand its occurrences count in the TValue, so the result would look like:

Keys:     Values:
{ cc kk }   2  //because those appear together in this order in 2 sublist(s)
{ cc oo }   1  //because those appear together in this order in 1 sublist(s)
{ cc jj }   1  //et cetera
{ ww oo }   2
{ ww gg }   1
{ kk ll }   1  //<-note that those do not appear in this order twice
{ ll kk }   1  
{ mm nn }   2  

As a hint i also have a linq command that does the same, except not with lists of string but with regular strings:

The strings i was talking about:

List<string> list = new List<string>();

{ gg }
{ gg }
{ jj }
{ ww }
{ ww }
{ jj }
{ mm } 
{ ww }
{ ll }
{ kk }
{ ll }

Linq command:

var dic = list.GroupBy(b => b).ToDictionary(group => group.Key, group => group.Count());

The dictionary:

Dictionary<string, int> otherOccurrences = dic;

Result of it:

Keys:     Values:
{ gg }      2      //because it appears in this list 2 time(s)
{ jj }      2      //same with this one
{ ww }      3      //et cetera
{ mm }      1
{ ll }      2
{ kk }      1

I would really appreciate the help with editing the specified linq command to get the one that would analogically do to the same to my occurrences. Feel free to correct me if im wrong somewhere. Im sorry if i did not make myself clear, feel free also to ask if you did not understand so i can explain it more specificly.

  • Try this `jaggedList.GroupBy(lst => string.Join("", lst.Take(x))) .ToDictionary(el => el.Key, el => el.Count());` – tchelidze Jan 28 '16 at 21:37
  • I checked couple of times your solution, turns out it you did it like my list was Dictionary occurrences = new Dictionary(); Instead of Dictionary, int> occurrences = new Dictionary, int>(); I didnt want x elements concatenated into one but literally x elements as a list. Could you help me again by fixing that? – goliatpiotr Jan 29 '16 at 00:19
  • Its probably my fault by putting broken declaration that had list on the left side and string on the right. Sorry. – goliatpiotr Jan 29 '16 at 00:25
  • as i see you managed to solve you problem, you can post your solution as an answer. – tchelidze Jan 29 '16 at 07:52

1 Answers1

1

The main problem to tackle is equality. Two "identical" lists aren't equal. Even if they contain the same elements, they're still different objects. You have to supply an IEqualityComparer to the GroupBy function:

var n = 2;
var dic = list.Select(l => l.Take(n))
              .GroupBy(b => b, new IEnumerableComparer<string>())
              .ToDictionary(group => group.Key, group => group.Count());

The IEnumerableComparer compares lists by their contents. There can be many ways to implement it. One decent example is here: IEqualityComparer for SequenceEqual.

Community
  • 1
  • 1
Gert Arnold
  • 105,341
  • 31
  • 202
  • 291
  • Id rather do it like @tchelidze did, except he made a mistake i just noticed. He did it like my dictionary had string as a key so he concatenated x elements into one instead of literally adding x elements as a list, like my dictionary is declared (Dictionary, int> occurrences = new Dictionary, int>();) – goliatpiotr Jan 29 '16 at 00:23