簡體   English   中英

如何使用擴展方法使集合成為“n”元素?

[英]How to make a collection be “n” elements long using extension methods?

所以,這是我的問題,我有一個給定的對象,它是一個IEnumerable,我保證所說的集合總是最多有4個元素。 現在,由於一個不重要的原因,我希望能夠以一種優雅的方式“強制”該集合包含4個元素(如果它沒有更少)。

我已經完成了一些研究,而且最令人信服的候選人是Zip,但它在收到最短的收集結束后就會停止拉鏈。

有沒有辦法在沒有自己的擴展方法的情況下這樣做? 為了更好地解釋自己:

var list1 = new List<Dog> {
    new Dog { Name = "Puppy" }
}
var list2 = new List<Dog> {
    new Dog { Name = "Puppy1" },
    new Dog { Name = "Puppy2" },
    new Dog { Name = "Puppy3" },
    new Dog { Name = "Puppy4" },
}

var other1 = list1.ExtendToNElements(4).ToList();
//Now other1's first element is an instance of Dog with Name = "Puppy"
//And the following 3 elements are null, or have a Dog with no name
//I don't really care about that

var other2 = list2.ExtendToNElements(4).ToList();
//other2 is the same as list2, nothing got added.

提前致謝!

快速單行(應該算作“沒有擴展方法可行”):

public static IEnumerable<TItem> Extend<TItem>(
            this IEnumerable<TItem> source, 
            int n)
{
    return source.Concat(Enumerable.Repeat(default(TItem), n))
                 .Take(n);
}

由於Repeat采用顯式計數,因此傳入n給出了合理的上限。 無論如何,元素都是按需生成的。 使用source.Count()會強制執行不理想的source

稍微過度設計和靈活的版本:

public static IEnumerable<TItem> Extend<TItem>(
            this IEnumerable<TItem> source, 
            int n, 
            Func<TItem> with) 
{
    return source.Concat(
        from i in Enumerable.Range(0, n) select with()
    ).Take(n);
}

public static IEnumerable<TItem> Extend<TItem>(
            this IEnumerable<TItem> source, 
            int n, 
            TItem with = default(TItem)) 
{
    return source.Extend(n, with: () => with);
}

您可以使用MoreLinq的Pad方法: http//code.google.com/p/morelinq/ (NuGet: http ://www.nuget.org/packages/morelinq)

這將附加類型的默認值(在本例中為null ):

var other1 = list1.Pad(4).ToList();

或者,如果要提供默認值:

var other1 = list1.Pad(4, "Puppy_null").ToList();

或者如果你想要那些編號的小狗:

var other1 = list.Pad(4, (count) => "Puppy" + count).ToList();

如果Pad方法的長度已經等於或大於您的焊盤尺寸,則Pad方法不會添加其他條目。

如果你想在不引入整個項目的情況下整合/改編它,那么這就是Pad實現: http//code.google.com/p/morelinq/source/browse/MoreLinq/Pad.cs

    class Program
    {
        static void Main(string[] args)
        {
            List<string> list = new List<string>();
            list.Capacity = 4;
            var items = list.TakeOrDefault(4);


        }
    }

    public static class EnumerableExtensions
    {
        public static IEnumerable<T> TakeOrDefault<T>(this IEnumerable<T> enumerable, int length)
        {
            int count = 0;
            foreach (T element in enumerable)
            {
                if (count == length)
                    yield break;

                yield return element;
                count++;
            }
            while (count != length)
            {
                yield return default(T);
                count++;
            }
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM