【问题标题】:Is there An Efficient way of combining two collections?有没有一种组合两个集合的有效方法?
【发布时间】:2015-08-05 08:12:51
【问题描述】:

我的课程如下:

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 和 TotalZ 分别由 GameT、ExT 和 GameZ、ExZ 相加得到。我有一个可观察的分数和经验集合,我想从中创建另一个总计集合,这是我到目前为止所做的:

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

它可以工作,但速度太慢,尤其是当记录开始达到数百时。有没有更好的办法?

【问题讨论】:

  • 我认为您当前的代码甚至无法编译 - tt.Id=scr.Id should be just Id=scr.Id` - 对象初始化程序中 = 的 LHS 不能包含 .
  • 如果体验总是与特定游戏直接相关,为什么要将两者作为单独的集合?为什么不是一个单一的游戏集合,每个游戏都有两个属性 - 分数和经验?
  • 可能是重复的,但我觉得这个问题有另一种解决方案,而不是使用join(我正要按下发布按钮时关闭...)
  • @JonSkeet 更正了编译错误。
  • 了解我们在谈论多少分数、多少经验以及“太慢”有多慢也很有用。我不认为只有“数百”条记录会成为问题。

标签: c# loops nested-loops


【解决方案1】:

看起来您只需要一个 LINQ 内部联接:

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

通过迭代所有体验开始,按 ID 收集它们,然后迭代分数,将每个分数与相关体验的集合相匹配,这样会更有效。基本上它将 O(M * N) 操作转换为 O(M + N) 操作。

【讨论】:

    【解决方案2】:

    也许我弄错了,但是观察可观察的集合并实时收集总计并在某处累积结果而不是尝试一次性解决问题不是一个好主意吗?

    这都是关于实现观察者/可观察模式的。由于您可以订阅集合更改,因此您可以在集合更改时执行操作。您还可以在Experience.ExTExperience.ExZ 上实现INotifyPropertyChanged,并订阅所有对象的每个属性的更改。

    这样,您无需处理数百个对象,而只需显示一段时间内积累的内容。

    【讨论】:

      猜你喜欢
      • 2011-04-12
      • 1970-01-01
      • 2011-08-10
      • 2016-08-13
      • 1970-01-01
      • 2021-07-22
      • 1970-01-01
      • 1970-01-01
      • 2023-03-09
      相关资源
      最近更新 更多