在C#中为OrderedDictionary串行赋值

时间:2015-11-04 09:03:33

标签: c# ordereddictionary

我有两个键值对,现在我想用一个较小的值以串行方式填充较大的值。

  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值以保持循环pickersToTicketMap并连续更新其值。

pickersToTicketMap有序列表最初的值为:

   ("100", "null");
   ("109", "null");
   ("13", "null");
   ("23", "null");

所以我需要PickerPool orderedDictionary的值以重复的方式填充这些空值。

4 个答案:

答案 0 :(得分:2)

听起来你应该从List<string>(或者可能是List<int>开始,因为它们似乎都是整数......)而不是用空条目填充你的地图。如下所示:

List<string> tickets = new List<string> { "100", "109", "13", "23" };

然后您可以将pickersToTicketMap填充为:

var pickers = pickersPool.Values;
var pickerIterator = pickers.GetEnumerator();
foreach (var ticket in tickets)
{
    if (!pickerIterator.MoveNext())
    {
        // Start the next picker...
        pickerIterator = pickers.GetEnumerator();
        if (!pickerIterator.MoveNext())
        {
            throw new InvalidOperationException("No pickers available!");
        }
    }
    ticketToPickerMap[ticket] = pickerIterator.Current;
}

请注意,我已将名称从pickersToTicketMap更改为ticketToPickerMap,因为这似乎就是您的真正含义 - 关键是故障单,值是选择器。

另请注意,我pickers处理迭代器。这通常是一个坏主意,但在这种情况下,我假设OrderedDictionary.Values.GetEnumerator()返回的迭代器不需要处理。

答案 1 :(得分:1)

您可能正在寻找:

Red, Blue
Blue, Red

PS: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++; } 需要有一个单独的密钥副本,因此您不会因为更改正在迭代的元素而获得ToArray()

答案 2 :(得分:0)

所以你想用可能更小的连续和重复值来更新大字典的值吗?我有两种方法,一种更简单:

  1. 您可以使用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];
    
  2. 我更喜欢上面的方法,因为它比我使用“无限”序列的第二种方法更具可读性。这是扩展方法:

    public static IEnumerable<T> RepeatEndless<T>(this IEnumerable<T> sequence)
    {
        while (true)
            foreach (var item in sequence)
                yield return item;
    }
    
  3. 现在您可以使用此代码更新较大字典的值:

    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<string>().ToList()非常重要,因为我无法使用原始Keys集合。如果在枚举期间更改它,则会出现异常。

答案 3 :(得分:0)

感谢@jon双向飞碟,虽然他在试图为此提供黑客攻击时过多地修改了我的对象。

在查看您的解决方案之后,我实现了以下内容,这适用于我的所有对象。

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