I have simple task where I need to check objects in one dictionary and if certain criteria met move to another. What I am asking if there is some good pattern where I can use language feature to achieve that. The straight approach is simple - use temporaty collection, first step determine canditates, second step do actual move. It is ok but it is not cool.
Current code
class Order
{
public int ID;
public bool IsReady;
}
Dictionary<int, Order> ActiveDictionary;
Dictionary<int, Order> ProcessedDictionary;
public Update()开发者_如何学Go
{
// 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);
}
}
There is nothing really wrong with the code you have.
As an exercise in alternatives, you could do something like...
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);
if Rex M's answer is not suitable (maybe you don't want to rebuild Dictionaries on each iteartion), then as small improvement I can suggest to replace
// temporary list, uncool
List<Order> processed = new List<Order>();
// fist step
foreach(Order ord in ActiveDictionary)
{
if(ord.IsReady)
{
processed.Add(ord);
}
}
to
var processed = ActiveDictionary.Where(x=>x.Value.Ready).ToArray();
and the rest of your code would be
foreach(var item in processed)
{
ActiveDictionary.Remove(item.Key);
ProcessedDictionary.Add(item.Key, item.Value);
}
UPD: As Ani commented, there is another alike solution:
var processed = ActiveDictionary.Values.Where(x=>x.Ready).ToArray();
foreach(var item in processed)
{
ActiveDictionary.Remove(item);
ProcessedDictionary.Add(item.Id, item);
}
try this
var keys = ActiveDictionary
.Where(kv => kv.Value.Ready)
.Select(kv => kv.Key).ToList();
keys.ForEach(k =>
{
ProcessedDictionary.Add(k, ActiveDictionary[k]);
ActiveDictionary.Remove(k);
});
精彩评论