2014-01-28 71 views
1

我有一個列表,例如List/IEnumerable中的重複數字

List<int> List1 = new List<int>{1, 5, 8, 3, 9}; 

什麼是重複的元素列表中的,以獲得一個簡單的方法{1,1,5,5,8,8,3,3,9,9}?

我需要這個的原因是我正在繪製列表中的元素,需要製作一個「步驟圖」。

+0

爲什麼不把當前值分配給局部變量並使用兩次? – Rik

回答

7
var list2 = List1.SelectMany(x => new []{x, x}).ToList(); 
+0

可能希望使lambda'x => new [] {x,x}'爲每個元素保存另一個'List'的開銷。 +1無論如何;) – Jamiec

+2

@Jamiec對於所有的意圖和目的,兩者之間的開銷差異很小。他們都會爲每個元素分配一個大小爲2的數組。你可以嘗試使用'x => Enumerable.Repeat(2,x)'來代替。這可能會降低GC開銷。 – Aron

+0

@Aron - 好點。更好的主意! – Jamiec

0

這是你想減少內存分配:

// Pre-allocate the space to save time 
List<int> dups = new List(List1.Count * 2); 

// Avoid allocating an enumerator (hopefully!) 
for(int i=0; i<List1.Count; i++) 
{ 
    var value = List1[i]; 
    dups.Add(value); 
    dups.Add(value); 
} 

這不是LINQ的,但它的內存使用效率,

3

我想創建(擴展)方法,列舉源,併產生每個項目需要的次數:

public static IEnumerable<T> RepeatItems<T>(this IEnumeable<T> source, int count) 
{ 
    foreach(var item in source) 
     for(int i = 0; i < count; i++) 
      yield return item; 
} 

因此,您將避免創建巨大的n陣列的數目。用法:

var result = List1.RepeatItems(2).ToList(); 

如果你只需要複製的項目,然後解決就更簡單了:

public static IEnumerable<T> DuplicateItems<T>(this IEnumeable<T> source) 
{ 
    foreach(var item in source) 
    { 
     yield return item; 
     yield return item; 
    } 
} 

DuplicateItems擴展的用途:

var result = List1.DuplicateItems().ToList(); 

此外,如果你只列舉結果,那麼你不需要將其轉換爲列表。如果您不會修改(添加/刪除)結果項目,那麼將其轉換爲數組效率更高。

+0

'RepeatItems'看起來像是Enumerable.Repeat的重複http://msdn.microsoft.com/en-us/library/bb348899(v=vs .110).aspx – Jodrell

+0

@Jodrell no,'RepeatItems'創建序列,每個原始序列項目重複。默認'Repeat'只是創建從單個項目重複的序列 –

2

從上述評論兩者,

var sequence2 = List1.SelectMany(x => Enumerable.Repeat(x, 2)); 

是更好的解決方案,原因是其避免了存儲器無意義分配。在開銷的變化會變得更加重要的情況下,更改爲n也會更簡單。

+0

我不知道關於內存使用情況,我可以相信一個兩元素數組小於由'Enumerable.Repeat'創建的迭代器。 – Rawling

+0

@Rawling但是一個兩元素數組和它的迭代器比'Enumerable.Repeat'創建的迭代器更大。更不用說,首先要寫數組的開銷。 – Aron