Группировка, приводящая к анонимным типам
У меня есть список строк, таких как эта
heading1 00:01:20
randomText
01:23
randomText2
01:45
randomText3
02:10
heading2 00:05:20
randomText4
07:25
randomText5
04:35
randomText6
09:12
etc.
Я хотел бы использовать Linq, чтобы получить список анонимных типов, таких как
{ Name = "randomText1", Category = "Heading1", Duration = "01:23"}
{ Name = "randomText2", Category = "Heading1", Duration = "01:45"}
...
{ Name = "randomText6", Category = "Heading2", Duration = "09:12"}
Есть ли способ, которым я мог бы достичь такого результата с Linq to Objects? Я понимаю, как было бы легко добиться этого, используя циклы for, но мне интересно, есть ли более чистый способ сделать это с помощью Linq, и я не могу найти ни одного.
1 ответ
Решение
Это делает трюк со следующими условиями:
1) Строка заголовка может быть распознана, она начинается с постоянного значения (вы можете изменить это условие, если хотите)
2) Для каждой строки "randomtext" может быть найдена соответствующая строка продолжительности.
var data = new List<string>() {
"heading1 00:01:20",
"randomText ",
"01:23 ",
"randomText2 ",
"01:45 ",
"randomText3 ",
"02:10 ",
"heading2 00:05:20",
"randomText4 ",
"07:25 ",
"randomText5 ",
"04:35 ",
"randomText6 ",
"09:12 "
};
const string HEADINGSTART = "heading"; // TODO: Set correct value
var temp = Enumerable.Range(0, data.Count - 1) // Iterate based on index
.Where(i => data[i].StartsWith(HEADINGSTART)) // Find the headings
.Select(i => new { // Project to heading + data
Heading = data[i],
Data = data.Skip(i + 1).TakeWhile(d => !d.StartsWith(HEADINGSTART)).ToList()
})
.SelectMany(d => d.Data.Select(d2 => new { // Project to single enumerable
Heading = d.Heading,
Data = d2
}))
.ToList();
var result = Enumerable.Range(0, temp.Count / 2) // Again, iterate based on index
.Select(i => new { // Project to requested object
Name = temp[i * 2].Data,
Category = temp[i * 2].Heading,
Duration = temp[i * 2 + 1].Data
})
.ToList();