2016-04-05 37 views
1

有張貼了類似的問題,但我沒有代表問一個後續問題在該線程:(刪除列表元素多次出現的更到位

這個問題和解決方案是HERE

如果我有一個列表包含的項目出現多次,List.Distinct()將刪除重複,但原始仍然會保留在原位如果我想刪除不止一次的項目,包括原始,什麼會是對原始列表執行此操作的最有效方式嗎?

給定一個名爲oneTi的列表我: { 4, 5, 7, 3, 5, 4, 2, 4 }

所需的輸出將是一次性的: { 7, 3, 2 }

感謝您的幫助!

----編輯和後續問題的@enigmativity,8April2016 -----------------

這裏是我的腳本的僞版本是在做。它是在.NET3.5上運行的NinjaTrader中完成的。

我會附上關於代碼應該做什麼的一般概念,我會附上實際的腳本,但除非使用NinjaTrader,否則可能無法使用。

但基本上,有一個大的z循環。每次通過時,都會在'LiTics'中添加一系列數字。我不想打擾。然後我將該列表傳遞給該函數,並返回僅出現一次的值列表。然後我希望每次都能看到這些數字。

它最初起作用,但是在各種數據集上運行它,經過幾次循環後,它開始報告不止一次出現的值。我不確定爲什麼?

for(int z=1; z<=10000; z +=1)//Runs many times 
{ 
    if (BarsInProgress ==0 &&CurrentBar-oBarTF1>0 &&startScript) //Some Condition 
    { 
     for(double k=Low[0]; k<=High[0]; k +=TickSize) 
     { 
      LiTics.Add(k); 
      //Adds a series of numbers to this list each time through z loop 
      //This is original that I do not want to disturb 
     } 

     LiTZ.Clear(); //Display list to show me results Clear before populating 
     LiTZ=GetTZone(LiTics); //function created in thread(below) 
           //Passing the undisturbed list that is modified on every loop 
     foreach (double prime in LiTZ) { Print(Times[0] +", " +prime); } 
     //Printing to see results 
    } 

}//End of bigger 'z' loop 

//Function created to get values that appear ONLY once 
public List<double> GetTZone(List<double> sequence) 
{ 
    var result = 
     sequence 
      .GroupBy(x => x) 
      .Where(x => !x.Skip(1).Any()) 
      .Select(x => x.Key) 
      .ToList(); 
    return result; 

} 

打印出來什麼的圖片是哪裏錯了: http://i.stack.imgur.com/pXcdK.jpg

+0

那你爲什麼不把結果分配給原始列表呢? – rcs

回答

4

所以,如果你能有一個新的列表,那麼這就是做最簡單的方法:

var source = new List<int>() { 4, 5, 7, 3, 5, 4, 2, 4 }; 

var result = 
    source 
     .GroupBy(x => x) 
     .Where(x => !x.Skip(1).Any()) 
     .Select(x => x.Key) 
     .ToList(); 

這給:

 
{ 7, 3, 2 } 

如果您想從原始來源中刪除這些值,請執行以下操作:

var duplicates = 
    new HashSet<int>(
     source 
      .GroupBy(x => x) 
      .Where(x => x.Skip(1).Any()) 
      .Select(x => x.Key)); 

source.RemoveAll(n => duplicates.Contains(n)); 
+0

是否有任何已知的問題可以調用多少次?我有一個函數,通過創建一個新的列表來執行上面的代碼,從第一個例子。它的工作原理與最初一樣,但在重複調用它之後,它會開始返回列表,該列表不止一次出現。 – pelt

+0

@佩特 - 這應該每一次都有效。你能否展示一些失敗的示例代碼? – Enigmativity

+0

附上上面的例子,我似乎遇到了標記爲「編輯」的問題。顯示列表中只出現一次值的腳本出現在循環中,該循環將爲每個增量添加值。每次我想顯示一次出現的值的列表,稍後我會用這些值做一些事情。 – pelt

-1

我對你有兩種選擇,一是使用HashSetLinq

選項1:

使用HashSet,遍歷集合,如果它不存在,如果它存在刪除插入。

HashSet<int> hash = new HashSet<int>(); 

foreach(var number in list) 
{ 
    if(!hash.Contains(number)) hash.Add(number); 
    else hash.Remove(number);    
} 
list = hash.ToList(); 

選項2:

簡單Linq,組的元件和過濾器,其計>1

var list= list.GroupBy(g=>g) 
    .Where(e=>e.Count()==1) 
    .Select(g=>g.Key) 
    .ToList(); 

存在使用HashSet性能增益超過Linq,很明顯,Linq(在這種情況下)需要多次迭代,其中作爲HashSet使用單次迭代,並且提供查找(用於添加/刪除)與O(1)訪問。

Elapsed Time (Using Linq): 8808 Ticks 
Elapsed Time (Using HashSet): 51 Ticks 

工作Demo

+0

爲什麼要投票?請expalin。 –

+0

作爲OP我沒有投票。我剛回來看到這個......我不知道誰是downvote? – pelt

+0

@佩特很遺憾,人們沒有解釋原因而投下了票。 –

相關問題