按键分组顺序列表

时间:2014-12-08 21:32:21

标签: c# linq

我正在尝试将相关条目列表分组。

我的列表如下:

new List<string>() { "Entry1", "Metadata1", "Metadata2", 
                       "Entry2", "Metadata3", "Metadata4" };

我想对“条目”进行分组,以便最终以{ "Entry1", "Metadata1", "Metadata2" }{ "Entry2", "Metadata3", "Metadata4" }作为群组。

“条目”字段之间的项目数是不确定的。我想用LINQ完成这个。

如何将这些分组到由Entry元素分隔的集合中?

5 个答案:

答案 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();
            }


        }
    }
}

输出如您所愿:

enter image description here

答案 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 
相关问题