Frage

Jeder! Wie kann ich minimalen Wert eines int-Array in bestimmtem Bereich in C # bekommen? Beispielsweise: int [] array = new int {1,2,3,4,5,6,7,8,76,45}; Und ich möchte einen minimalen Wert zwischen 3-rd bekommen und 8-ten Elemente. Vielleicht ist es möglich, über LINQ-Abfragen zu bekommen?

War es hilfreich?

Lösung

array.Skip(2).Take(5).Min();

Andere Tipps

Ich denke, ich kann auch meine tuppence diesem hinzufügen. Als Jason auf die Tatsache, Objekte, die wir sagen, wie viele wir eher als Ende Index sind Skipping, können wir eine einfache Erweiterung Methode hinzufügen:

public static IEnumerable<T> WithIndexBetween<T>(this IEnumerable<T> source,
    int startInclusive, int endExclusive)
{
    // The two values can be the same, yielding no results... but they must
    // indicate a reasonable range
    if (endExclusive < startInclusive)
    {
        throw new ArgumentOutOfRangeException("endExclusive");
    }
    return source.Skip(startInclusive).Take(endExclusive - startInclusive);
}

Dann:

int min = array.WithIndexBetween(2, 7).Min();

Stellen Sie die Extension-Methode Namen Geschmack. (Naming ist hart, und ich werde nicht im Alter mit einem schön man kommt hier verbringen:)

int min = array.Where((value, index) => index >= 2 && index <= 7).Min(); 

EDIT

Eigentlich über dem Ansatz ist sehr ineffizient, weil es die ganze Sequenz aufzählt, obwohl wir nicht in Einzelteile mit einem Index interessiert höher als 7. Eine bessere Lösung zu verwenden TakeWhile wäre:

int min = array.TakeWhile((value, index) => index <= 7).Skip(2).Min();

Leider ist es nicht sehr gut lesbar ... Die beste Option, es zu machen schöneren wahrscheinlich eine benutzerdefinierte Erweiterung Methode zu schaffen, wie in Jons Antwort gezeigt.

int[] arr = {0,1,2,3,4,5,6,7,8};
int start = 3;
int end = 8;
int min = arr.Skip(start - 1).Take(end - start).Min();

Nur eine weitere Option hinzuzufügen:

int start = 3;
int end = 8;
var min = Enumerable.Range(start - 1,end - start).Select(idx => array[idx]).Min();

AFAIK, ist dies „theorically“ schneller, wenn Sie einen Bereich in der Nähe des Ende des einen nehmen, und das Array ist wirklich sehr, sehr lange.

Das ist, weil (wieder AFAIK) Skip() Rechnung nicht nehmen, die ein Array ist (das heißt kann zufällig in O zugegriffen werden (1)) und zählt auf es trotzdem.

array.Skip(3).Take(4).Min();

Ich persönlich würde das vorziehen:

public static class ArrayExtensions {
    public static bool ArrayAndIndexesAreValid(
        T[] array,
        int startInclusive,
        int endExclusive
    ) {
    return array != null &&
           array.Length > 0 &&
           startInclusive >= 0 && startInclusive < array.Length &&
           endExclusive >= 1 && endExclusive <= array.Length &&
           startInclusive < endExclusive;
    }
    public static IEnumerable<T> Slice<T>(
        this T[] array,
        int startInclusive,
        int endExclusive
    ) {
        Contract.Requires<ArgumentException>(ArrayAndIndexesAreValid(
            array,
            startInclusive,
            endExclusive)
        );
        for (int index = startInclusive; index < endExclusive; index++) {
            yield return array[index];
        }
    }
    public static T MinimumInIndexRange<T>(
        this T[] array,
        int startInclusive,
        int endExclusive
    ) where T : IComparable {
        Contract.Requires<ArgumentException>(ArrayAndIndexesAreValid(
            array,
            startInclusive,
            endExclusive)
        );
        return array.Slice(startInclusive, endExclusive).Min();
    }

    public static T MaximumInIndexRange<T>(
        this T[] array,
        int startInclusive,
        int endExclusive
    ) where T : IComparable {
        Contract.Requires<ArgumentException>(ArrayAndIndexesAreValid(
            array,
            startInclusive,
            endExclusive)
        );
        return array.Slice(startInclusive, endExclusive).Max();
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top