2015-11-04 3 views
1

У меня есть две пары ключевых значений, теперь я хочу заполнить более крупную со значениями меньшего размера последовательным образом.Последовательное назначение значений в OrderedDictionary C#

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 значения, чтобы сохранить выборки на велосипедеToTicketMap и обновлять его значение серийно.

Edit:

orderedlist pickersToTicketMap изначально имеет значение

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

так что мне нужно для значений PickerPool orderedDictionary, чтобы заполнить эти пустые значения в многократной моде.

+2

Откуда берутся 100, 109, 13 и 23 части? Боюсь, я нахожу ваш вопрос очень трудным для понимания ... Пожалуйста, отредактируйте его, чтобы быть более четким. –

+0

Вы хотите знать, как сделать что-то вроде sql-соединения в C#? – AntiHeadshot

+0

@JonSkeet отредактировал, –

ответ

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(), не нуждается в утилизации.

+0

@TimSchmelter: Да - я проголосовал за закрытие, потому что изначально было очень неясно. Затем выяснилось, насколько я могу ответить, тогда некоторые другие люди подумали, что еще неясно ответить. Проголосовали за повторное открытие. –

+0

эта линия ticketToPickerMap [билет] = pickerIterator.Current не возвращает значение «System.Collections.DictionaryEntry» вместо захватывающего числа –

+1

@Edwin: Вы уверены, что у вас есть * точно * мой код, с помощью ' var pickers = pickersPool.Values; '? Я намеренно повторяю только коллекцию значений, * не * над 'pickersPool'. –

1

является

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 из-за изменения элемента, который вы перебираете.

+0

Не могли бы вы объяснить, что именно делает ваш код? – CodeCaster

+0

@CodeCaster добавлено разъяснение – AntiHeadshot

0

Итак, вы хотите обновить значения большого словаря последовательными и повторяющимися значениями из возможно меньшего? У меня есть два подхода, один простой:

1.) Вы можете повторить меньшую коллекцию с помощью Enumerable.Repeat. Вы должны сгладить счет. Затем вы можете использовать SelectMany, чтобы сгладить его и ToList, чтобы создать коллекцию. Затем вы можете использовать для цикла обновления большего словаря со значениями в списке с помощью индекса:

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

Теперь вы можете использовать этот код для обновления значения более крупного словаря:

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

Благодаря @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(); 
       } 
Смежные вопросы