首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在OrderedDictionary中串行地为C#赋值

在OrderedDictionary中串行地为C#赋值
EN

Stack Overflow用户
提问于 2015-11-04 09:03:32
回答 4查看 352关注 0票数 1

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

代码语言:javascript
复制
  OrderedDictionary pickersPool = new OrderedDictionary(); // Small
  OrderedDictionary pickersToTicketMap = new OrderedDictionary(); // Big

  pickersPool.Add("emp1", 44);
  pickersPool.Add("emp2", 543);

现在我需要更新pickersToTicketMap如下所示:

代码语言:javascript
复制
   ("100", 44);
   ("109", 543);
   ("13", 44);
   ("23", 543);

因此,基本上,我需要pickersPool值来循环pickersToTicketMap字典的键。

我需要pickerPool值来保持循环pickersToTicketMap并按顺序更新它的值。

pickersToTicketMap订单列表最初的值为:

代码语言:javascript
复制
   ("100", "null");
   ("109", "null");
   ("13", "null");
   ("23", "null");

因此,我需要PickerPool orderedDictionary的值来重复地填充这些空值。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-11-04 09:36:00

听起来你应该从List<string>开始(或者可能是List<int>,因为它们看起来都是整数.)而不是从一开始就用空条目填充地图。所以,就像:

代码语言:javascript
复制
List<string> tickets = new List<string> { "100", "109", "13", "23" };

然后,您可以将pickersToTicketMap填充为:

代码语言:javascript
复制
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()返回的迭代器不需要处理。

票数 2
EN

Stack Overflow用户

发布于 2015-11-04 09:32:18

也许你想要的是:

代码语言:javascript
复制
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

票数 1
EN

Stack Overflow用户

发布于 2015-11-04 10:10:35

因此,您想从可能较小的字典中用连续的和重复的值更新大字典的值吗?我想到了两种方法,一种更简单:

  1. 您可以使用Enumerable.Repeat重复较小的集合。你得算一算。然后,您可以使用SelectMany来扁平它,使用ToList来创建一个集合。然后,您可以使用for循环通过索引更新包含列表中的值的较大字典: IEnumerable值= pickersPool.Values.Cast();if (pickersPool.Count < pickersToTicketMap.Count) { //重复此集合,直到其大小与较大的集合值= Enumerable.Repeat(值,pickersToTicketMap.Count / pickersPool.Count + pickersToTicketMap.Count % pickersPool.Count ) .SelectMany(intColl => intColl);} List valueList = values.ToList();for (int i= 0;i< valueList.Count;i++) valueList.Count=values.ToList;
  2. 我更喜欢上述方法,因为它比我使用“无限”序列的第二个方法更易读。这是扩展方法: 公共静态IEnumerable RepeatEndless(此IEnumerable序列){this (true) foreach (var item in IEnumerable)产生返回项;}

现在,您可以使用此代码更新较大字典的值:

代码语言:javascript
复制
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集合。如果在枚举期间更改异常,则会得到异常。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33517620

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档