简体   繁体   English

根据编号拆分字符串列表

[英]Splitting List Of Strings Based on Numbering

I have several numbered lists stored in a List<string> : 我在List<string>中存储了几个编号列表:

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

I want to split this list into a list of lists where each list contains 1-3. 我想将此列表拆分为列表列表,其中每个列表包含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"}
}

There will ALWAYS be "1." 总会有“ 1”。 so I can use that as my delimiter. 因此我可以将其用作分隔符。 Is there a slick way to do this with LINQ without needing two nested for loops? 有没有一种巧妙的方法可以使用LINQ做到这一点,而无需两个嵌套的for循环?

Update: I'd like this to be generalized for any length, not always 3. 更新:我希望将其概括为任意长度,而不总是3。

Sounds like you could use the dictionary type instead. 听起来您可以改用字典类型。 Rather than storing the number of the item and the item itself, you can set the item number as the key and the item itself as the value. 您可以将项目编号设置为键,将项目本身设置为值,而不是存储项目编号和项目本身。 Here is an example of how you might accomplish that: 这是您可能如何完成此操作的示例:

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

You can iterate through each item, or use a method to call by keys or values. 您可以遍历每个项目,或使用一种方法来按键或值进行调用。

List<List<string>> result = all.GroupAdjacent((g, x) => !x.StartsWith("1."))
                               .Select(g => g.ToList())
                               .ToList();

using the GroupAdjacent Extension Method from here . 此处使用GroupAdjacent扩展方法

Just another option to get desired result (assign group index to each item in sequence, then group by that index): 获得期望结果的另一种选择(将组索引分配给每个项目,然后按该索引分组):

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();

Another option - accumulate results (this will require one traverse over the list) 另一种选择-累积结果(这需要遍历列表)

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; 
                    });  

There's not really a slick way of doing this using LINQ without making a bunch of assumptions about the list, and the only guaranteed bit of information that you've given us is "there will always be a 1." 如果不对列表做一堆假设,使用LINQ确实没有一种巧妙的方法,而且您提供给我们的唯一保证的信息是“总会有1”。 . Will there always be groups of 3 items, or will there sometimes be more or less? 总是会有3件物品的组合,还是有时会有更多或更少的组合?

Why not change the way the strings are stored to begin with - use a List<List<string>> instead, so you have a List of List<string> ? 为什么不改变字符串存储到开始的方式-使用List<List<string>>代替,让你有一个ListList<string>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM