Is there an efficient way to combine two collections?
I have classes like this:
public class Root
{
public int Id {get;set;}
public string PlayerName{get;set;}
}
public class Scores:Root
{
public int GameT{get;set;}
public int GameZ{get;set;}
}
public class Experience:Root
{
public int ExT{get;set;}
public int ExZ{get;set;}
}
public class Total:Root
{
public int TotalT{get;set;}
public int TotalZ{get;set}
}
TotalT and TotalZ come from the addition of GameT, ExT and GameZ, ExZ respectively. I have an observable collection of points and experiences from which I want to create another Total collection, this is what I have done so far:
public ObservableCollection<Total> GetTotal(ObservableCollection<Scores> scores,ObservableCollection<Experience> experiences)
{
var tc= new ObservableCollection<Total>();
foreach(var scr in scores)
{
foreach(var exp in experiences)
{
if(scr.Id==exp.Id)
{
var tt= new Total{
Id=scr.Id,
Name=scr.PlayerName,
TotalT=scr.GameT+exp.Ext,
TotalZ=scr.GameZ+exp.Exz
};
tc.Add(tt);
}
}
}
return tc;
}
It works, but it's too slow, especially when the records start hitting the hundreds. Is there a better way?
source to share
It looks like you just need a LINQ inner join:
var query = from score in scores
join exp in experiences on score.Id equals exp.Id
select new Total {
Id = score.Id,
Name = score.PlayerName,
TotalT = score.GameT + exp.Ext,
TotalZ = score.GameZ + exp.Exz
};
return new ObservableCollection<Total>(query);
This would be more efficient by repeating all the events to start with, collecting them by ID, then iterating over the results, matching each score against a collection of related events. Basically it turns an O (M * N) operation into an O (M + N) operation.
source to share
Maybe I'm wrong, but would it be nice to observe observable collections and collect real-time totals and accumulate the results somewhere instead of trying to fix the problem right away?
It's all about embedding an observable / observable pattern. Since you can subscribe to changes to the collection, you can do anything whenever the collection changes. You can also implement INotifyPropertyChanged
on Experience.ExT
and Experience.ExZ
and subscribe to changes to each property from all objects.
This way, you don't have to work with hundreds of objects, but you just show what has been accumulated over a period of time.
source to share