如何在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)'有一些无效参数
我该怎么做?
我写这段代码的目的就是:
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;
}