如何在c#中使用Linq块字典

本文关键字:Linq 字典 | 更新日期: 2023-09-27 18:06:37

我有一个字典,我需要将它块到一个组中的9个字典项列表和其他9个条目到下一个组,等等…,

试过此代码,

    public static List<List<DictionaryEntry>> ChunkDict(Dictionary<string,string> theList, int chunkSize) 
    { 
        List<List<DictionaryEntry>> result = theList.Select((x, i) => 
            new { data = x, indexgroup = i / chunkSize })
            .GroupBy(x => x.indexgroup, x => x.data)
            .Select(g => new List<DictionaryEntry>(g)).ToList(); 
        return result; 
    } 

但没有编译,得到错误:错误398最佳重载方法匹配'System.Collections.Generic.List.List(System.Collections.Generic.IEnumerable)'有一些无效参数

我该怎么做?

如何在c#中使用Linq块字典

我写这段代码的目的就是:

public static class EnumerableExtensions
{
    public static IEnumerable<IEnumerable<TElement>> Partition<TElement>(this IEnumerable<TElement> @this, int partitionSize)
    {
        if (@this == null) throw new ArgumentNullException("this");
        return new PartitionedEnumerable<TElement>(@this, partitionSize);
    }
    private sealed class PartitionedEnumerable<TElement> : IEnumerable<IEnumerable<TElement>>
    {
        #region Public
        public PartitionedEnumerable(IEnumerable<TElement> elements, int partitionSize)
        {
            this.elements = elements;
            this.partitionSize = partitionSize;
        }
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
        public IEnumerator<IEnumerable<TElement>> GetEnumerator()
        {
            IEnumerator<TElement> elementEnumerator = this.elements.GetEnumerator();
            var partition = new List<TElement>();
            while (elementEnumerator.MoveNext())
            {
                partition.Add(elementEnumerator.Current);
                if (partition.Count == partitionSize)
                {
                    yield return partition;
                    partition = new List<TElement>();
                }
            }
            if (partition.Count > 0) yield return partition;
        }
        #endregion
        #region Private
        private readonly IEnumerable<TElement> elements;
        private readonly int partitionSize;
        #endregion
    }
}

的例子:

IDictionary<string, string> dictionary = ...;
foreach (IEnumerable<KeyValuePair<string, string>> triplet in dictionary.Partition(3))
{
    ... // use the triplet
}

如果您希望它们作为字典返回:

IEnumerable<Dictionary<string, string>> partitioned = dictionary.Partition(3)
                                                                .Select(_ => _.ToDictionary());

使用这个答案中的示例代码:

public static IEnumerable<IEnumerable<T>> Split<T>(this IEnumerable<T> list, int parts)
{
    int i = 0;
    var splits = from name in list
                 group name by i++ % parts into part
                 select part.AsEnumerable();
    return splits;
}

也许你可以修改它以适用于你的Dictionary列表

你试过吗?

    public static Dictionary<int,List<Dictionary<string,string>> ChunkDict(Dictionary<string,string> theList, int chunkSize) 
    { 
        var result = theList.Select((x, i) => 
            new { data = x, indexgroup = i / chunkSize })
            .GroupBy(x => x.indexgroup)
            .Select(new KeyValuePair<int, List<Dictionary<string,string>>>(x.Key, x.ToList())).ToDictionary(); 
        return result; 
    } 
编辑:

可能需要一点修改,我甚至没有编译这段代码

这是我写的一个分块算法,可能对你有帮助

public static IEnumerable<IEnumerable<TResult>> SelectChunk<TSource, TResult>(
        this IEnumerable<TSource> source, Func<TSource, TResult> selector, int chunkSize)
    {
        IEnumerator<TSource> enumerator = source.GetEnumerator();
        while(true)
        {
            if (!enumerator.MoveNext())
                break;
            var resultArray = new TResult[chunkSize];
            for (int i = 0; i < chunkSize; i++)
            {
                resultArray[i] = selector(enumerator.Current);
                if (i == chunkSize-1 || !enumerator.MoveNext())
                    break;
            }
            yield return resultArray;
        } 
    }

编辑

你可以这样使用它:

dictionary.SelectChunk(s => s, 9).Select(s => s.ToList).ToList()

您没有访问组项中的数据,请尝试:

    public static void Main(string[] args)
    {
        var dict = new Dictionary<string, string> { { "1", "one" }, { "2", "two" }, { "3", "three" }, { "4", "four" }, { "5", "five" }, { "6", "six" } };
        var lists = ChunkDict(dict, 2);
        var i = 0;
        foreach (var list in lists)
        {
            Console.WriteLine("List with index {0} has count {1}", i, list.Count);
            foreach (var dictionaryEntry in list)
            {
                Console.WriteLine(dictionaryEntry.Key + ": " + dictionaryEntry.Value);
            }
            i++;
        }
        Console.ReadLine();
    }
    public static List<List<KeyValuePair<string, string>>> ChunkDict(Dictionary<string, string> theList, int chunkSize)
    {
        var result = theList.Select((x, i) =>
            new { data = x, indexgroup = i / chunkSize })
            .GroupBy(x => x.indexgroup, x => x.data)
            .Select(y => y.Select(x => x).ToList()).ToList();
        return result;
    }