C# 在C中为OrderedDictionary连续赋值
我有两个键值对,现在我想用较小的键值对以串行方式填充较大的键值对C# 在C中为OrderedDictionary连续赋值,c#,ordereddictionary,C#,Ordereddictionary,我有两个键值对,现在我想用较小的键值对以串行方式填充较大的键值对 OrderedDictionary pickersPool = new OrderedDictionary(); // Small OrderedDictionary pickersToTicketMap = new OrderedDictionary(); // Big pickersPool.Add("emp1", 44); pickersPool.Add("emp2", 543); 现在我需要将picke
OrderedDictionary pickersPool = new OrderedDictionary(); // Small
OrderedDictionary pickersToTicketMap = new OrderedDictionary(); // Big
pickersPool.Add("emp1", 44);
pickersPool.Add("emp2", 543);
现在我需要将pickersToTicketMap更新为如下所示:
("100", 44);
("109", 543);
("13", 44);
("23", 543);
所以基本上我需要pickersPool值来循环遍历pickersToTicketMap字典的键
我需要pickerPool值来不断循环PickerToticketMap并连续更新其值
pickersToTicketMap orderedlist最初的值为:
("100", "null");
("109", "null");
("13", "null");
("23", "null");
因此,我需要PickerPool orderedDictionary的值以重复的方式填充这些空值。可能有您想要的:
using System.Linq;
...
int i = 0;
// Cast OrderedDictionary to IEnumarable<DictionaryEntry> to be able to use System.Linq
object[] keys = pickersToTicketMap.Cast<DictionaryEntry>().Select(x=>x.Key).ToArray();
IEnumerable<DictionaryEntry> pickersPoolEnumerable = pickersPool.Cast<DictionaryEntry>();
// iterate over all keys (sorted)
foreach (object key in keys)
{
// Set the value of key to element i % pickerPool.Count
// i % pickerPool.Count will return for Count = 2
// 0, 1, 0, 1, 0, ...
pickersToTicketMap[key] = pickersPoolEnumarable
.ElementAt(i % pickersPool.Count).Value;
i++;
}
PS:ToArray需要有一个单独的键副本,这样您就不会因为更改正在迭代的元素而得到InvalidOperationException。听起来您应该从一个列表或可能的列表开始,因为它们似乎都是整数。。。而不是一开始就用空条目填充地图。比如:
List<string> tickets = new List<string> { "100", "109", "13", "23" };
请注意,我已将名称从pickersToTicketMap更改为ticketToPickerMap,因为这似乎是您真正的意思-键是票据,值是选择器
还要注意,我并没有从选择器中处理迭代器。这通常是个坏主意,但在本例中,我假设OrderedDictionary.Values.GetEnumerator返回的迭代器不需要处理。那么您想用可能较小的迭代器中的连续值和重复值更新大词典的值吗?我有两种方法,一种更简单: 可以使用Enumerable.repeat重复较小的集合。你得计算一下总数。然后可以使用SelectMany将其展平,然后使用ToList创建集合。然后,您可以使用for循环通过索引使用列表中的值更新较大的字典:
IEnumerable<int> values = pickersPool.Values.Cast<int>();
if (pickersPool.Count < pickersToTicketMap.Count)
{
// Repeat this collection until it has the same size as the larger collection
values = Enumerable.Repeat( values,
pickersToTicketMap.Count / pickersPool.Count
+ pickersToTicketMap.Count % pickersPool.Count
)
.SelectMany(intColl => intColl);
}
List<int> valueList = values.ToList();
for (int i = 0; i < valueList.Count; i++)
pickersToTicketMap[i] = valueList[i];
我更喜欢上面的方法,因为它比使用无限序列的第二种方法更可读。这是扩展方法:
public static IEnumerable<T> RepeatEndless<T>(this IEnumerable<T> sequence)
{
while (true)
foreach (var item in sequence)
yield return item;
}
现在,您可以使用以下代码更新较大字典的值:
var endlessPickersPool = pickersPool.Cast<DictionaryEntry>().RepeatEndless();
IEnumerator<DictionaryEntry> endlessEnumerator;
IEnumerator<string> ptmKeyEnumerator;
using ((endlessEnumerator = endlessPickersPool.GetEnumerator()) as IDisposable)
using ((ptmKeyEnumerator = pickersToTicketMap.Keys.Cast<string>().ToList().GetEnumerator()) as IDisposable)
{
while (endlessEnumerator.MoveNext() && ptmKeyEnumerator.MoveNext())
{
DictionaryEntry pickersPoolItem = (DictionaryEntry)endlessEnumerator.Current;
pickersToTicketMap[ptmKeyEnumerator.Current] = pickersPoolItem.Value;
}
}
请注意,使用largerDict.Keys.Cast.ToList很重要,因为我不能使用原始的Keys集合。如果您在枚举过程中更改它,您会得到一个异常。多亏了@jon skeet,尽管他在尝试提供此方法时修改了我的对象太多 在查看了您的解决方案之后,我实现了以下内容,这对我的所有对象都很有效
var pickerIterator = pickerPool.GetEnumerator();
foreach (DictionaryEntry ticket in tickets)
{
if (!pickerIterator.MoveNext())
{
// Start the next picker...
pickerIterator = pickerPool.GetEnumerator();
if (!pickerIterator.MoveNext())
{
throw new InvalidOperationException("No pickers available!");
}
}
ticketToPickerMap[ticket.Key] = pickerIterator.Value.ToString();
}
100、109、13和23部件来自哪里?恐怕我觉得你的问题很难理解。。。请将其编辑得更清楚。您想知道如何在c中执行类似sql联接的操作吗?@AntiHeadshot这不是sql而是cSo听起来您需要一个选择器列表,然后有一个嵌套循环来填充pickersToTicketMap…是的@JonSkeet,这正是我想要的,以这种方式。44,543,下一个选择者。。。。。最后一个选择者,44,543……你介意解释一下你的代码到底做了什么吗?@CodeCaster补充道explanation@TimSchmelter当前位置是-我投票决定关闭,因为它最初非常不清楚。然后它被澄清到我可以回答的程度,然后其他一些人认为它仍然太不清楚,无法回答。已投票决定立即重新打开。此行ticketopickermap[ticket]=PickerEditor.Current未返回System.Collections.DictionaryEntry而不是picker的值number@Edwin:使用var pickers=pickersPool.Values;,您确定您完全掌握了我的代码吗;?我故意只迭代values集合,而不是pickersPool。
var pickerIterator = pickerPool.GetEnumerator();
foreach (DictionaryEntry ticket in tickets)
{
if (!pickerIterator.MoveNext())
{
// Start the next picker...
pickerIterator = pickerPool.GetEnumerator();
if (!pickerIterator.MoveNext())
{
throw new InvalidOperationException("No pickers available!");
}
}
ticketToPickerMap[ticket.Key] = pickerIterator.Value.ToString();
}