2

我有几个编号列表存储在List<string>

List<string> all = new List<string>()
{
  "1. Apple",
  "2. Banana",
  "3. Coconut",
  "1. Ant",
  "2. Beaver",
  "3. Cat"
  ...
}

我想将此列表拆分为列表列表,其中每个列表包含 1-3。

List<List<string>> split = new List<List<string>>()
{
  new List<string>() { "1. Apple", "2. Banana", "3. Coconut"},
  new List<string>() { "1. Ant", "2. Beaver", "3. Cat"}
}

总会有“1”。所以我可以用它作为我的分隔符。有没有一种巧妙的方法可以用 LINQ 做到这一点,而不需要两个嵌套的 for 循环?

更新:我希望这可以概括为任何长度,而不是总是 3。

4

4 回答 4

2

听起来您可以改用字典类型。您可以将项目编号设置为键,将项目本身设置为值,而不是存储项目的编号和项目本身。以下是您如何完成此操作的示例:

newList = {'1':'Apple','2':'Banana','3':'Pear'}  
animalList = {'1':'Bear','2':'Cat','3':'Dog'}

您可以遍历每个项目,或使用方法通过键或值调用。

于 2012-12-08T23:28:55.627 回答
2
List<List<string>> result = all.GroupAdjacent((g, x) => !x.StartsWith("1."))
                               .Select(g => g.ToList())
                               .ToList();

这里使用GroupAdjacent 扩展方法

于 2012-12-08T23:29:00.510 回答
1

获得所需结果的另一种选择(按顺序为每个项目分配组索引,然后按该索引分组):

int groupIndex = 0;
List<List<string>> split = all.Select(s => {
                                   if (s.StartsWith("1."))
                                      groupIndex++;
                                   return new { groupIndex, s }; })
                              .GroupBy(x => x.groupIndex)
                              .Select(g => g.Select(x => x.s).ToList())
                              .ToList();

另一种选择 - 累积结果(这将需要遍历列表)

List<List<string>> split =
    all.Aggregate(new List<List<string>>(), (acc, s) =>
                    { 
                        if (s.StartsWith("1."))
                            acc.Add(new List<string>());
                        acc[acc.Count - 1].Add(s);
                        return acc; 
                    });  
于 2012-12-09T00:08:46.050 回答
0

如果不对列表进行大量假设,使用 LINQ 执行此操作并没有真正的巧妙方法,而且您提供给我们的唯一有保证的信息是“总会有 1”。. 总是有 3 个项目的组,还是有时会更多或更少?

为什么不改变字符串的存储方式开始 - 使用 aList<List<string>>代替,所以你有 a Listof List<string>

于 2012-12-08T23:31:21.387 回答