2015-01-18 2 views
1

Я должен создать метод расширения jump<T>, который, взятый произвольной последовательностью s, возвращает бесконечную последовательность, элементы которой получаются посещением круговым способом s и пропусканием n элементов. Итак, если step == 0, то вся последовательность возвращается (бесконечное время), если шаг == 1, возьмем все числа в интервале [0-10] в качестве примера, вернет 0,2,4, 6,8,10,1,3,5 ecc. Если шаг == 2, то результат будет 0,3,6,9,1,4,7,10. Очевидно, что это всего лишь пример с упорядоченным списком int, мне нужно сделать это с помощью общей последовательности элементов T.Элементы ToSkip в круговом списке C#

Как я могу это достичь?

Чтобы проверить это, я создал тест NUnit следующим образом:

[Test] 
     public void Jumping_validArg_IsOk() 
    { 

     var start = new[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11} 
      .Jumping(3) 
      .ToList()//remove this to make it work 
      .Take(4); 
     var expected = new[] {1, 5, 9, 2}; 
     CollectionAssert.AreEquivalent(start, expected); 
    } 

но, кажется, никогда не закончится, и он бросает System.OutOfMemoryException.

Решение: Я изменил немного, что я выбрал, как лучший ответ, чтобы сделать его более общий характер таким образом:

 public static IEnumerable<T> Jump<T>(this IEnumerable<T> sequence, int step) 
     { 
      var pos = 0; 
      var list = sequence.ToList(); 
      while (true) 
      { 
       yield return list[pos]; 
       pos = (pos + step + 1) % list.Count; 
      } 
     } 

Таким образом, он должен работать со всеми IEnumerable. Я добавил комментарий к тесту, чтобы показать, что удалить, чтобы заставить его работать. Надеюсь, все будет правильно.

+0

Вам не нужно 'ToList()'. И это хорошо, потому что, когда он используется так, он никогда не вернется. –

+0

@HenkHolterman да, вы правы, теперь это работает. – Sanci

ответ

2

Вы можете осуществить это очень легко с yield return утверждением:

public static IEnumerable<T> Jump<T>(this IList<T> data, int step) { 
    int pos = 0; 
    while(true) { 
     yield return data[pos]; 
     pos = (pos + step) % data.Count; 
    } 
} 
+1

'IList <>' не является непосредственно «произвольной последовательностью». –

+0

Я пробовал это, но тест, который я только что опубликовал на моем отредактированном вопросе, даже не заканчивается. Возможно, я написал тест не так. И я изменил ваш ответ, используя 'data.ToList() [pos]', чтобы я мог использовать аргумент IEnumerable в качестве аргумента. – Sanci

+1

@Sanci - Да, трудно проверить что-то, что «бесконечно» –

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