SORU
22 Kasım 2009, Pazar


Nasıl ama bir dizi SERİ kullanarak son elemanı almak?

Hadi bir sırası var.

IEnumerable<int> sequence = GetSequenceFromExpensiveSource();
// sequence now contains: 0,1,2,3,...,999999,1000000

Sıra alma, ucuz değildir ve dinamik olarak oluşturulur, ve sadece bir kez yinelemek istiyorum.

0 - 999999 (her şeyi ama son öğe gibi) almak istiyorum

Gibi bir şey yapabilirim diye hatırlıyorum:

sequence.Take(sequence.Count() - 1);

ama bu büyük sıra iki numaralandırma sonuçları.

Orada bir SERİ yapmamı sağlayan yapısı:

sequence.TakeAllButTheLastElement();

CEVAP
22 Kasım 2009, Pazar


Seri bir çözüm bilmiyorum - Ama kolayca jeneratörler (getiri) kullanılarak algoritma kodu.

public static IEnumerable<T> TakeAllButLast<T>(this IEnumerable<T> source) {
    var it = source.GetEnumerator();
    bool hasRemainingItems = false;
    bool isFirst = true;
    T item = default(T);

    do {
        hasRemainingItems = it.MoveNext();
        if (hasRemainingItems) {
            if (!isFirst) yield return item;
            item = it.Current;
            isFirst = false;
        }
    } while (hasRemainingItems);
}

static void Main(string[] args) {
    var Seq = Enumerable.Range(1, 10);

    Console.WriteLine(string.Join(", ", Seq.Select(x => x.ToString()).ToArray()));
    Console.WriteLine(string.Join(", ", Seq.TakeAllButLast().Select(x => x.ToString()).ToArray()));
}

Ya da genelleştirilmiş bir çözüm son n öğeleri atarak (yorum önerdiğin gibi bir sıra kullanarak):

public static IEnumerable<T> SkipLastN<T>(this IEnumerable<T> source, int n) {
    var  it = source.GetEnumerator();
    bool hasRemainingItems = false;
    var  cache = new Queue<T>(n   1);

    do {
        if (hasRemainingItems = it.MoveNext()) {
            cache.Enqueue(it.Current);
            if (cache.Count > n)
                yield return cache.Dequeue();
        }
    } while (hasRemainingItems);
}

static void Main(string[] args) {
    var Seq = Enumerable.Range(1, 4);

    Console.WriteLine(string.Join(", ", Seq.Select(x => x.ToString()).ToArray()));
    Console.WriteLine(string.Join(", ", Seq.SkipLastN(3).Select(x => x.ToString()).ToArray()));
}

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • InfoPuppet

    InfoPuppet

    15 Kasım 2011
  • iMasterful

    iMasterful

    11 EYLÜL 2009
  • Matthew Morrill

    Matthew Morr

    15 EKİM 2011