2009-04-15 20 views
9

Haskell'den intersperse function'u öğrendim ve C# 'da bir uygulama arıyorlar.Enumerable.Intersperse için uzantısı yöntemi?

Intersperse, 2 bağımsız değişkeni, bir IEnumerable <T> kaynağını ve bir T öğesini alır. Kaynağın her unsuru arasına yerleştirilmiş eleman ile IEnumerable döndürür.

olası bir kullanım-case örneğin tamsayılar listesi arasına keyfi bir tamsayı koymaktır:

// returns: {1, 0, 2, 0, 3} 
(List<int>() {1, 2, 3}).Intersperse(0); 

Bu string.join (...) genel bir durumdur. Bunu nasıl uygulanacağını merak ediyorsanız

cevap

12

Something diğerleri kaçırmış: önünde veya arkasında değil de yalnızca öğeler arasında saklarım istiyorsanız ve , fazladan bir kontrol yapmak gerekir: bir çözüm yukarı kodlu ettik

public static IEnumerable<T> Intersperse<T>(this IEnumerable<T> source, T element) 
{ 
    bool first = true; 
    foreach (T value in source) 
    { 
     if (!first) yield return element; 
     yield return value; 
     first = false; 
    } 
} 
+0

Ah için! beni ona yen! – Daniel

+0

Gerçekten, saniyeler içinde ... –

+0

Amacınız mantıklı, ama cevabınız karıştı. Örneğinizde, serpiştirilmiş öğenin önce geleceğini düşünüyorum, ki bu doğru sanmıyorum. –

-2

, böyle bunu olacaktır:

public static IEnumerable<T> Intersperse<T>(this IEnumerable<T> collection, T value) 
{ 
    foreach(T item in collection) 
    { 
     yield return item; 
     yield return value; 
    } 

    yield break; 
} 
+2

var, diyeceksin birini pek çok "değer" ler –

5

Linq çözümleri ruhu içinde, tembel olduğunu! Geldiğim diğer çözümler, verileri geri göndermeden önce tüm listeyi geçmeye ve sonuçta ortaya çıkan listeye geri dönmeyi içeriyordu.

Diğer yanıtların bazıları, döngünün her yinelemesinde bir kontrol varsa.

public static IEnumerable<T> Intersperse<T>(this IEnumerable<T> source, T element) 
{ 
    using (var enumerator = source.GetEnumerator()) { 
     if (enumerator.MoveNext()) { 
      yield return enumerator.Current; 
      while (enumerator.MoveNext()) { 
       yield return element; 
       yield return enumerator.Current; 
      } 
     } 
    } 
} 
+1

GetEnumerator() öğesini kullanırken, Discovery() yineleyici –

+0

@Marc'ı kullanmalısınız, bunu işaretlediğiniz için teşekkür ederiz! – Daniel

+2

Koleksiyonun büyük olması durumunda dallanmayı ortadan kaldırmak güzel. Bu arada, n + 1 veya n-1 şeylere ihtiyacınız olan klasik bir "Çit Sonrası Sorunu". 'String.Join()', C# ların bunlarla temas etmelerinin en yaygın yoludur. –

2

Yazmak için çok kolay olurdu:

public static IEnumerable<T> Intersperse<T>(this IEnumerable<T> source, T value) { 
    bool first = true; 
    foreach(T item in source) { 
     if(first) { first = false; } 
     else { yield return value; } 
     yield return item; 
    } 
} 
İlgili konular