4

だから、ここに私の問題があります.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.

前もって感謝します!

4

3 に答える 3

4

クイックワンライナー(「拡張メソッドなしで実行可能」と見なされるはずです):

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);
}
于 2012-12-13T23:14:26.063 に答える
3

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プロジェクト全体を取り込まずに組み込み/適応させたい場合の具体的な実装は次のとおりです。http://code.google.com/p/morelinq/source/browse/MoreLinq/Pad.cs

于 2012-12-13T23:11:32.353 に答える
0
    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++;
            }
        }
    }
于 2012-12-13T23:17:12.797 に答える