Reputation: 863
From a tab limited text file like this, first row: names of columns, rest of the rows the values for eahc column,...
Col1 Col2 Col3 Col4 Col5 Col6 Col7 Col8....
Val1 Val2 Val3 Val4 Val5 Val6 Val7 Val8...
abc1 abc2 abc3 abc4 abc5 abc6 abc7 abc8...
.....
......
......
I have made a Dictionary<combinedKey, List<MyRows> myList>
where combinedKey
is values for Col1+Col2+Col3
so I have made a key based on those, and then if there are more rows in the file with the same combinedKey
I am making a list of them, so that's why it is a dictionary
.
And it serves the purpose of the thing I am doing so far based on requirements. I am not gonna hcange that! That's what I need for that part of the problem. :)
Now in some other part of the program I need another combinedKey
, this time: Col1+Col2+Col3+Col4+Col5
Is there a way I can utilize my previously parsed and populted dictionary above?
Upvotes: 1
Views: 336
Reputation: 13286
Interesting question. Unfortunately there isn't really a great way to do this, at least that I know of. No matter what you're going to have to touch each record multiple times, so you might as well just use LINQ for both groups and have them independent. This will, at least, be more readable.
I'll just pretend your data is tab-delimited. Given that, you can do something like this.
var rows = File.ReadAllLines(filePath).Select(c =>
{
string[] args = c.Split(\t);
return new
{
Col1 = args[0],
Col2 = args[1],
Col3 = args[2],
Col4 = args[3],
Col5 = args[4],
Col6 = args[5],
Col7 = args[6],
Col8 = args[7]
};
}).ToArray(); // I wouldn't use ToArray here if you were only looking for one grouping, since that would be less efficient on memory and CPU usage
var groupedByThree = rows.GroupBy(c => c.Col1 + c.Col2 + c.Col3);
var groupedByFive = rows.GroupBy(c => c.Col1 + c.Col2 + c.Col3 + c.Col4 + c.Col5);
I know this is more than you were asking about, since I included some parsing logic which is almost definitely not applicable to your particular situation. But that's how I'd do it. Build a flat list first, then group each set independently.
I mean, of course, you could always do something similar to this and use the parsing and grouping you've already got, but it wouldn't be more performant in the complexity sense, and I think it's less readable.
var dict = new Dictionary<combinedKey, List<MyRows>>(); // your data here
var dimensioned = dict.ToDictionary(c => c.Key, c => c.Value.ToDictionary(x => x.Col4 + x.Col5));
As you can read, this creates a dictionary of dictionaries that looks something like this:
{
col1col2col3
{
col4col5
{
individual records
}
}
}
You can flatten that out as you please. Although if you can, I'd leave it hierarchical like that. You can use this like this:
foreach(var record in dict[col1col2col3][col4col5])
{
// handle
}
Or you could even reverse to get the original dictionary:
dict[col1col2col3].SelectMany(c => c.Value);
In fact, I'd be tempted to parse the original dictionary into something like this right from the start, then you're only storing it once in memory. But again I would just parse it all using LINQ.
Upvotes: 1