7

クエリを実行すると、リストに少なくとも 183 個のアイテムが含まれていると予想されますが、抽出結果の結果のアイテム数が 183 未満になることがあります。

if (extractArray.Count() < 183) {
    int arraysize= extractArray.Count();
    var tempArr = new String[183 - arraysize];
    List<string> itemsList = extractArray.ToList<string>();
    itemsList.AddRange(tempArr);
    var values = itemsList.ToArray();
    //-- Process the new array that is now at least 183 in length
}

しかし、私の解決策は最善ではないようです。抽出が行われるたびに、少なくとも 183 個のアイテムを確実に取得するのに役立つ他のソリューションをいただければ幸いです。

4

4 に答える 4

8

私はおそらく他の人の提案に従い、リストを使用します。パフォーマンスを向上させるには、「capacity」コンストラクターを使用します。

var list = new List<string>(183);

次に、新しい配列を取得するたびに、これを実行します (" " を、配列のパディングに使用する値に置き換えます)。

list.Clear();
list.AddRange(array);
// logically, you can do this without the if, but it saves an object allocation when the array is full
if (array.Length < 183)
    list.AddRange(Enumerable.Repeat(" ", 183 - array.Length));

このようにして、リストは常に同じ内部配列を再利用し、割り当てと GC の負荷を軽減します。

または、拡張メソッドを使用できます。

public static class ArrayExtensions
{
    public static T ElementOrDefault<T>(this T[] array, int index)
    {
        return ElementOrDefault(array, index, default(T));
    }
    public static T ElementOrDefault<T>(this T[] array, int index, T defaultValue)
    {
        return index < array.Length ? array[index] : defaultValue;
    }
}

次に、次のようにコーディングします。

items.Zero = array[0];
items.One = array[1];
//...

これになります:

items.Zero = array.ElementOrDefault(0);
items.One = array.ElementOrDefault(1);
//...

最後に、これは私がこの回答を書き始めたかなり面倒なアイデアです。183 個のインデックスを持つことが保証されている IList 実装で配列をラップできます (簡潔にするために、ほとんどのインターフェイス メンバーの実装を省略しました)。

class ConstantSizeReadOnlyArrayWrapper<T> : IList<T>
{
    private readonly T[] _array;
    private readonly int _constantSize;
    private readonly T _padValue;

    public ConstantSizeReadOnlyArrayWrapper(T[] array, int constantSize, T padValue)
    {
         //parameter validation omitted for brevity
        _array = array;
        _constantSize = constantSize;
        _padValue = padValue;
    }

    private int MissingItemCount
    {
        get { return _constantSize - _array.Length; }
    }

    public IEnumerator<T> GetEnumerator()
    {
        //maybe you don't need to implement this, or maybe just returning _array.GetEnumerator() would suffice.
        return _array.Concat(Enumerable.Repeat(_padValue, MissingItemCount)).GetEnumerator();
    }

    public int Count
    {
        get { return _constantSize; }
    }

    public bool IsReadOnly
    {
        get { return true; }
    }

    public int IndexOf(T item)
    {
        var arrayIndex = Array.IndexOf(_array, item);
        if (arrayIndex < 0 && item.Equals(_padValue))
            return _array.Length;
        return arrayIndex;
    }

    public T this[int index]
    {
        get
        {
            if (index < 0 || index >= _constantSize)
                throw new IndexOutOfRangeException();
            return index < _array.Length ? _array[index] : _padValue;
        }
        set { throw new NotSupportedException(); }
    }
}

わかりました。

于 2012-10-03T23:08:20.580 に答える
5

Array 基本クラスはResizeメソッドを実装します

if(extractArray.Length < 183)
    Array.Resize<string>(ref extractArray, 183);

ただし、サイズ変更はパフォーマンスに問題があることに注意してください。したがって、この方法は、何らかの理由で配列が必要な場合にのみ役立ちます。リストに切り替えることができれば

そして、ここに文字列の 1 次元配列があると仮定するので、Length プロパティを使用して、配列内の項目の有効数を確認します。

于 2012-10-03T21:21:11.673 に答える
2

183 個のインデックスがあることを確認する必要があり、ない場合はパディングする必要があると述べたので、配列の代わりにリストを使用することをお勧めします。次のようなことができます:

while (extractList.Count < 183)
{
     extractList.Add(" "); // just add a space
}

絶対に配列に戻らなければならない場合は、同様のものを使用できます。

于 2012-10-03T21:52:37.110 に答える
2

このソリューションをお勧めするとは言えませんが、だからといって投稿をやめることはできません! 彼らがそれを認めるかどうかにかかわらず、誰もが linq ソリューションが好きです!

linq を使用して、X 要素を含む配列を指定すると、次のように正確に Y (この場合は 183) 要素を含む配列を生成できます。

  var items183exactly = extractArray.Length == 183 ? extractArray :
                        extractArray.Take(183)
                                    .Concat(Enumerable.Repeat(string.Empty, Math.Max(0, 183 - extractArray.Length)))
                                    .ToArray();

要素が 183 未満の場合、配列は空の文字列で埋められます。183 を超える要素がある場合、配列は切り捨てられます。ちょうど 183 個の要素がある場合、配列はそのまま使用されます。

これが効率的であるとか、必ずしも良い考えであるとは主張しません。しかし、それは linq (yippee!) を使用しており、楽しいものです。

于 2012-10-04T17:43:15.400 に答える