2010-12-01 2 views
5

У меня есть простая задача, когда мне нужно проверять объекты в одном словаре, и если определенные критерии соответствуют переходу на другой. Я спрашиваю, есть ли хороший образец, где я могу использовать языковые возможности для достижения этого. Прямой подход прост - используйте временную коллекцию, первый шаг определите показатели, второй шаг - фактический ход. Это нормально, но это не круто.Как перемещать объект между словарями?

Текущий код

class Order 
{ 
    public int ID; 
    public bool IsReady; 
} 

Dictionary<int, Order> ActiveDictionary; 
Dictionary<int, Order> ProcessedDictionary; 

public Update() 
{  
// temporary list, uncool 
List<Order> processed = new List<Order>(); 


// fist step 
foreach(Order ord in ActiveDictionary) 
{ 
    if(ord.IsReady) 
    { 
    processed.Add(ord); 
    } 
} 

// ok now lets move 
foreach(Order ord in processed) 
{ 
    ActiveDictionary.Remove(ord.ID); 
    ProcessedDictionary.Add(ord.ID, ord); 
} 
} 

ответ

7

Там нет ничего на самом деле не так с кодом у вас есть.

В качестве упражнения в альтернативах, вы могли бы сделать что-то вроде ...

ProcessedDictionary = ProcessedDictionary 
    .Concat(
     ActiveDictionary.Where(kvp => kvp.Value.Ready) 
    ) 
    .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); 

ActiveDictionary = ActiveDictionary.Where(kvp => !kvp.Value.Ready) 
    .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); 
+0

Я получил чувствуя, что вы действительно хотите использовать `Where`, а не` Select`. Я сомневаюсь, что код компилируется так, как сейчас, поскольку вход в `ToDictionary`, вероятно, является значением` bool`. – 2010-12-01 12:27:08

+0

@Fredrik ha! вы правы, длинный день :) – 2010-12-01 12:27:41

+0

... и есть мой upvote :) – 2010-12-01 12:28:11

3

если ответ Rex M «s не подходит (может быть, вы не хотите, чтобы восстановить словарей на каждом iteartion) , то, как небольшое улучшение я могу предложить заменить

// temporary list, uncool 
List<Order> processed = new List<Order>(); 

// fist step 
foreach(Order ord in ActiveDictionary) 
{ 
    if(ord.IsReady) 
    { 
    processed.Add(ord); 
    } 
} 

в

var processed = ActiveDictionary.Where(x=>x.Value.Ready).ToArray(); 

и остальная часть кода будет

foreach(var item in processed) 
{ 
    ActiveDictionary.Remove(item.Key); 
    ProcessedDictionary.Add(item.Key, item.Value); 
} 

UPD: Как Ани комментировал, есть еще один похожий раствор:

var processed = ActiveDictionary.Values.Where(x=>x.Ready).ToArray(); 

foreach(var item in processed) 
{ 
    ActiveDictionary.Remove(item); 
    ProcessedDictionary.Add(item.Id, item); 
} 
1

попробовать этот

var keys = ActiveDictionary 
    .Where(kv => kv.Value.Ready) 
    .Select(kv => kv.Key).ToList(); 
keys.ForEach(k => 
     { 
      ProcessedDictionary.Add(k, ActiveDictionary[k]); 
      ActiveDictionary.Remove(k); 
     });