2011-03-16 100 views
0

我必須能夠列出可能包含具有特定標準的doubloon的對象列表。到目前爲止,代碼正在工作,但是我的列表中有50,000行需要10分鐘。我可以做些什麼來優化我的linq查詢嗎?

下面是代碼:

public class TestObject 
    { 
     public string value1; 
     public string value2; 
     public string value3; 
     public string value4; 

     public int num1; 
     public int num2; 
    } 

    public static List<TestObject> ReturnTestObjectListWithoutDoubloon(List<TestObject> source) 
    { 
     var destination = new List<TestObject>(); 
     var list = new Dictionary<int, TestObject>(); 


     while (source.Count > 0) 
     { 
      list.Clear(); 
      var originalElement = source[0]; 

      foreach (var query in source.Select((element, index) => new { Value = element, Index = index }) 
      .Where(currentElement => (currentElement.Value.value1 == originalElement.value1) 
            && (currentElement.Value.value2 == originalElement.value2) 
            && (currentElement.Value.value3 == originalElement.value3) 
            && (currentElement.Value.value4 == originalElement.value4))) 
      { 
       list.Add(query.Index, query.Value); 
      } 

      if (list.Count > 1) 
      { 
       originalElement.num1 = list.Sum(a => a.Value.num1); 
       originalElement.num2 = list.Sum(a => a.Value.num2); 
      } 

      destination.Add(originalElement); 
      foreach (var positionToremove in list.Keys) 
       source.RemoveAt(positionToremove); 
     } 

     return destination; 
    } 

的想法是每個所以我的LINQ的要求是最小的名單可能在執行我通過while循環時間縮短列表。然而,我擁有的金幣越少,速度就越慢。我正在尋找一種解決方案,使我可以擁有最小的rutnime,內存不是問題。

有沒有人有想法?

+0

杜布隆=雙重元素,你想要做的事,當你遇到這種情況? – Femaref 2011-03-16 17:58:38

+2

我聞到copypasta錯誤:你確定將value3與value4比較? (currentElement.Value.value3 == originalElement.value4) – 2011-03-16 18:02:38

+0

A doubloon是一枚金幣。我不明白與這個問題有什麼關係。 – Gabe 2011-03-16 18:02:51

回答

1

我試圖通過你的代碼 - 它看起來像你只是想從你的源列表中刪除重複?

如果是這樣的話:

  • 那麼我認爲你的source.RemoveAt代碼可能會被打破,因爲它可能會刪除錯誤的元素。

  • 那麼你應該能夠在這個源列表上運行一個單獨的GroupBy()操作 - 應該使用一個散列表,它應該比現有的循環內部循環操作快得多。

    var query = from s in source 
          group s by new { 
           value1 = s.value1, 
           value2 = s.value2, 
           value3 = s.value3, 
           value4 = s.value4 
          } into grouped 
          select new TestObject() 
          { 
           value1 = grouped.Key.value1, 
           value2 = grouped.Key.value2, 
           value3 = grouped.Key.value3, 
           value4 = grouped.Key.value4, 
           num1 = grouped.Sum(x => x.num1), 
           num2 = grouped.Sum(x => x.num2) 
          }; 
    return query.ToList(); 
    
+1

由於聚合結果的附加要求,「不同」將不起作用。 – Femaref 2011-03-16 18:13:40

+0

同意 - 我已經解決了這個問題,並且改變了答案 - 但爲時已晚......你已經擊敗了我!我會鼓勵你的... – Stuart 2011-03-16 18:19:00

+0

由於我存儲了我從查詢中得到的源代碼索引,所以我確信每個索引都是正確的。我在小列表上測試了我的代碼。雖然我可能在粘貼時犯了錯誤。你能告訴我哪個部分是問題嗎?我會試試這個,謝謝! – lollancf37 2011-03-16 22:47:47

3

如果我正確理解你的問題,你有多個元素具有相同的密鑰,並希望在這種情況下做一些事情。只是使用一組聲明:

source.GroupBy(s => new 
        { 
         Value1 = s.Value1, 
         Value2 = s.Value2, 
         Value3 = s.Value3, 
         Value4 = s.value4 
        }) 
     .Select(g => new TestObject 
        { 
         Value1 = g.Key.Value1, 
         Value2 = g.Key.Value2, 
         Value3 = g.Key.Value3, 
         Value4 = g.Key.value4, 
         Num1 = g.Sum(s => s.Num1), 
         Num2 = g.Sum(s => s.Num2) 
        }); 
+0

謝謝。就您的代碼和@Stuart之間的性能而言,您的看法有差異。我在問,因爲我從來沒有真正區別從IEnumerable對象調用操作符或使用Linq語法。我希望自己清楚O_o – lollancf37 2011-03-16 22:55:35

+0

不,完全沒有區別 - Stuart的代碼只是一種用更像sql語法編寫我的代碼的方法(它實際上應該翻譯成我的代碼)。查詢語法是以更可讀的方式表達複雜查詢的一種方式,但是它可以在LINQ中使用所有可能的功能。 – Femaref 2011-03-16 22:58:13

+0

好吧,這真的是一個味道的問題。謝謝。主要是, – lollancf37 2011-03-17 10:04:38

相關問題