我正在尝试将相关条目列表分组。
我的列表如下:
new List<string>() { "Entry1", "Metadata1", "Metadata2",
"Entry2", "Metadata3", "Metadata4" };
我想对“条目”进行分组,以便最终以{ "Entry1", "Metadata1", "Metadata2" }
和{ "Entry2", "Metadata3", "Metadata4" }
作为群组。
“条目”字段之间的项目数是不确定的。我想用LINQ完成这个。
如何将这些分组到由Entry
元素分隔的集合中?
答案 0 :(得分:3)
可能的解决办法是获取Entries
的索引,并使用GetRange
的{{1}}方法使用索引获取范围内的项目:
List<T>
答案 1 :(得分:2)
这是一个解决方案和输出。希望这是你想要做的。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
List<string> datas = new List<string>() { "Entry1", "Metadata1", "Metadata2", "Entry2", "Metadata3", "Metadata4" };
List<List<string>> grouped = new List<List<string>>();
int count = -1;
foreach (string e in datas)
{
if (e.StartsWith("Entry"))
{
grouped.Add(new List<string>());
grouped[++count].Add(e);
}
else
{
grouped[count].Add(e);
}
}
for (int i = 0; i < grouped.Count; i++)
{
for (int j = 0; j < grouped[i].Count; j++)
{
Console.WriteLine(grouped[i][j]);
}
Console.WriteLine();
}
}
}
}
输出如您所愿:
答案 2 :(得分:2)
您所追求的是IGrouping<TKey,TValue>
或ILookup<TKey,TValue>
。麻烦的是,您必须调用框架方法来生成不适用于此方案的框架方法,因为您无法提取密钥和值(如果使用字典,则可以提取密钥和多个值)每次迭代。在这种情况下使用LINQ的问题在于,为了获得您想要的内容,您必须多次迭代集合,以便正确地对所有内容进行分组。执行您要求的最有效方法是在for循环中手动检索数据并创建Dictionary<string, IEnumerable<string>>
,创建DictionaryEntries并在每次点击新密钥时添加它们。折衷方案是使用ToLookup投影数据,使用&#34;垃圾&#34;添加键的条目。然后你经过这个过滤的关键点:
var data = new List<string>() { "Key1", "Value1", "Value2",
"Key2", "Value3", "Value4" };
string workingKey = null;
data.ToLookup(item => {
if(item.StartsWith("Key"))
{
workingKey = item;
return String.Empty; //use whatever here
}
return workingKey;
}).Where(g => g.Key != String.Empty); //make sure to enumerate this if you plan on setting workingKey after this EDIT: Where is enumerating so no need to enumerate again
答案 3 :(得分:1)
这是一个想法(需要润色),在LINQPad中实现(这里是dotnetfiddle):
void Main()
{
var data = new List<string>() { "Entry1", "Metadata1", "Metadata2",
"Entry2", "Metadata3", "Metadata4" };
PairWithGroup(data).GroupBy(t=>t.Item1).Dump();
}
private IEnumerable<Tuple<string,string>> PairWithGroup(IEnumerable<string> input) {
string groupName = null;
foreach (var entry in input) {
if (entry.StartsWith("Entry")) {
groupName = entry;
}
yield return Tuple.Create(groupName, entry);
}
}
答案 4 :(得分:1)
.Net小提琴演示:https://dotnetfiddle.net/140PwW
<强>代码:强>
//create initial list
List<string> myList = new List<string>{"Entry1","a","b","Entry2","c","d","e"};
//remember previous group name
string previousGroupName = null;
//create grouped list
var myGroupedList =
myList.Select(i => new{
Value=i
,GroupName=(i.StartsWith("Entry")?(previousGroupName = i):previousGroupName)
})
.GroupBy(gb => gb.GroupName);
//output to LinqPad (if running there)
myGroupedList.Dump();
<强>结果:强>
Key = Entry1
Value GroupName
Entry1 Entry1
a Entry1
b Entry1
Key = Entry2
Value GroupName
Entry2 Entry2
c Entry2
d Entry2
e Entry2