2014-01-28 2 views
1

У меня есть список, например.Повторить номера в списке/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

может захотеть создать лямбда 'x => new [] {x, x}', чтобы сохранить накладные расходы другого «списка» для каждого элемента. +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)); 

является лучшим решением becuase избегает бессмысленного распределения памяти. Также было бы проще изменить на n повторений, где изменение накладных расходов станет более значительным.

+0

Я не знаю об использовании памяти, я могу поверить, что двухэлементный массив меньше, чем итератор, созданный' Enumerable.Repeat'. – Rawling

+0

@Rawling Но массив из двух элементов И его итератор больше, чем итератор, созданный 'Enumerable.Repeat'. Не говоря уже о накладных расходах на запись массива в первую очередь. – Aron

Смежные вопросы