C#, Linq – Wybieranie najlepszego z kolekcji.

Jest kolekcja obiektów i należy wybrać ten, który ma coś najlepszego. W tym przypadku wybieramy sałatę, którą najbardziej się najemy. Kod zazwyczaj wygląda tak:

Lettuce ChooseBestLettuce(List<Lettuce> lettuces)
{
    Lettuce bestLettuce = lettuces.First();
    double bestFood = bestLettuce.Food;

    foreach (var lettuce in lettuces)
    {
        if (lettuce.Food > bestFood)
        {
            bestLettuce = lettuce;
            bestFood = lettuce.Food;
        }
    }

    return bestLettuce;
}

Dzisiaj zauważyłem, że można zrobić to trochę mniej optymalnie, ale jednak kod się uprości. Będziemy tutaj musieli przebiec po pętli jeden dodatkowy raz (chociaż może tylko pół dodatkowego raza 😉 ).

Lettuce ChooseBestLettuceByLinq(List<Lettuce> lettuces)
{
    double bestFood = lettuces.Max(p => p.Food);
    return lettuces.First(p => p.Food == bestFood);
}

Update

Jak zasugerowa @karczk w komentarzu, można jeszcze lepiej:

Lettuce ChooseBestLettuceByLinq(List<Lettuce> lettuces)
{
    return lettuces
        .Aggregate((agg, next) => next.Food > agg.Food ? next : agg);
}

Przebiegamy tylko raz po liście. (Nie dodaję DefaultIfEmpty(), żeby nie łamać spójności z poprzednimi przykładami.)

Jeszcze prostsze rozwiązanie podał @karczk w komentarzu:

Lettuce ChooseBestLettuceByLinq(List<Lettuce> lettuces)
{
    return lettuces.OrderByDescending(p => p.Food).FirstOrDefault();
}

Kurcze, normalnie korzystam z OrderByDescending(), gdy chcę posortować zwracane wyniki. Jakoś jednak nie wpadłem na to zastosowanie.

Advertisements
Ten wpis został opublikowany w kategorii Programowanie i oznaczony tagami , . Dodaj zakładkę do bezpośredniego odnośnika.

4 odpowiedzi na „C#, Linq – Wybieranie najlepszego z kolekcji.

  1. karczk pisze:

    Można lepiej 😉 Poniższy kod obsługuje również pustą kolekcję:
    lettuces.DefaultIfEmpty().Aggregate((agg, next) => next.Food > agg.Food ? next : agg);

  2. Tooooo jest dobre! I do tego przebiega po kolekcji tylko raz.

  3. karek pisze:

    Mozna też: lettuces.OrderByDescending(p => p.Food).FirstOrDefault();

  4. W tym Linq już wszystko jest 🙂

Możliwość komentowania jest wyłączona.