Domanda

Mi aspetto di avere almeno 183 articoli nella mia lista quando la interrogo, ma a volte il risultato del mio estratto si traduce in oggetti inferiori al 183. La mia correzione corrente appare apparentemente la matrice nel caso in cui il conteggio sia inferiore a183.

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
}
.

Ma sembra che la mia soluzione non sia la migliore.Apprezzerei altre soluzioni che potrebbero contribuire a garantire di ottenere almeno 183 articoli ogni volta che l'estratto avviene per favore.

È stato utile?

Soluzione

La classe di base dell'array implementa il ridimensiona metodo

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

Tuttavia, tieni presente che il ridimensionamento è problematico per le prestazioni, quindi questo metodo è utile solo se si richiede l'array per qualche motivo.Se è possibile passare a un elenco

E, suppongo che tu abbia una serie unidimensionale di stringhe qui, quindi uso la proprietà della lunghezza per verificare il numero effettivo di elementi nell'array.

Altri suggerimenti

Probabilmente seguirei suggerimenti degli altri e usa una lista.Utilizzare il costruttore "Capacity" per prestazioni aggiuntive:

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

Quindi, ogni volta che ottieni un nuovo array, fallo (sostituire "" con qualsiasi valore che usi per ritagliare l'array):

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));
.

In questo modo, l'elenco riutilizza sempre lo stesso array interno, riducendo le allocazioni e la pressione GC.

Oppure, è possibile utilizzare un metodo di estensione:

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;
    }
}
.

Quindi codice come questo:

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

diventa questo:

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

Infine, questa è l'idea piuttosto ingombrante con cui ho iniziato a scrivere questa risposta: è possibile avvolgere l'array in un'implementazione ilist che è garantita per avere 183 indici (ho omesso la maggior parte delle implementazioni dei membri dell'interfaccia per Brevity): .

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(); }
    }
}
.

ack.

Poiché hai dichiarato di aver bisogno di garantire che ci siano 183 indici e che è necessario eseguire il ritmo se non ce n'è, suggerirei di utilizzare una lista invece di un array.Puoi fare qualcosa come:

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

Se devi assolutamente tornare a un array puoi usare qualcosa di simile.

Non posso dire che consiglierei questa soluzione, ma non lascerò farmi fermarmi di pubblicarlo!Che si piaccia ammetterlo o no, a tutti piacciono le soluzioni Linq!

Usando LINQ, data una matrice con elementi X in esso, è possibile generare un array con elementi esatti y (183 nei tuoi casi) in questo tipo:

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

Se ci sono meno di 183 elementi, l'array sarà imbottito con stringhe vuote.Se ci sono più di 183 elementi, l'array verrà troncato.Se ci sono esattamente 183 elementi, l'array è usato come è.

Non rivendico che questo sia efficiente o che sia necessariamente una buona idea.Tuttavia, usa Linq (Yippee!) Ed è divertente.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top