edit as question is unanswered
I have a filtered output based on 1 criteria (first 3 numbers are 110,210 or 310,to give 3 distinct groups) to console from streamreader.
(Posting this answer here, as the other question is closed.) Using ReadAllText will be inefficient for large files.
public static class LinqToTextReader {
public static IEnumerable<string> AsEnumerable(this TextReader reader) {
string line;
while ((line = reader.ReadLine()) != null) {
yield return line;
}
}
}
class Program {
static void Main(string[] args) {
using (StreamReader reader = new StreamReader("file.dat")) {
var locations = new Dictionary<string, int[]>() {
{"210", new [] {406, 409, 129, 140, 142, 153}},
{"310", new [] {322, 325, 113, 124, 126, 137}},
{"410", new [] {478, 481, 113, 124, 126, 137}}
};
var query =
from line in reader.AsEnumerable()
let lineStart = line.Substring(0, 3)
where lineStart == "210" || lineStart == "310" || lineStart == "410"
let currentLocations = locations[lineStart]
select new {
letters = line.Substring(currentLocations[0], currentLocations[1]),
value =
int.Parse(line.Substring(currentLocations[2], currentLocations[3])) +
int.Parse(line.Substring(currentLocations[4], currentLocations[5]))
};
//It should be possible to combine the two queries
var query2 =
from item in query
group item by item.letters into letterGroup
select new {
letters = letterGroup.Key,
total = letterGroup.Sum(item => item.value)
};
foreach (var item in query2) {
Console.WriteLine(item.letters);
Console.WriteLine(item.total);
}
}
}
}
string input = File.ReadAllText("file.dat");
var result = Regex.Matches(input, "(210|310|410).*?([A-C]{3})([0-9]{5})")
.Cast<Match>()
.Select(m => new {
P1 = m.Groups[1].Value,
P2 = m.Groups[2].Value,
P3 = Convert.ToInt32(m.Groups[3].Value)
})
.GroupBy(x => new{x.P1,x.P2})
.Select(x=>String.Format("{0} {1} {2}",x.Key.P1,x.Key.P2,x.Sum(y=>y.P3)))
.ToList();