2010-03-29 10 views

risposta

8

Suppongo che stiate cercando una accessor che restituisca l'ennesimo elemento di una collezione non ordinata eseguendo un ordinamento parziale sulla raccolta. Questo tende ad essere utile quando hai una collezione molto grande e sei interessato a uno dei primi elementi basato su un predicato di ordinamento.

A mia conoscenza, né le estensioni .NET BCL o LINQ offrono un equivalente. Tutti i metodi di ordinamento (incluso Enumerable.OrderBy) eseguono un ordine completo della raccolta.

Se è necessaria una versione efficiente di Nth, è necessario eseguire il proprio metodo di estensione su IEnumerable per farlo. Se hai intenzione di eseguire il rollover, potresti voler esaminare lo Quick Select algorithm, che ha prestazioni O (n).

Se la versione a forza bruta è sufficiente, è possibile utilizzare LINQ:

var someCollection = new []{ 5, 2, 8, 9, 0, 1, 3, 12, 4 }; 

var fifthItem = someCollection.NthItem(5); 

public static class NthExtensions 
{ 
    public static T NthItem(this IEnumerable<T> coll, int n) 
    { 
     return coll.OrderBy(x => x).Skip(n - 1).First(); 
    } 
} 
3

No, non è così. Dovrai scrivere manualmente l'algoritmo di selezione (preferibilmente quick select).

1

Non c'è un equivalente diretto. Potresti, potenzialmente, utilizzare LINQ's OrderBy e Take/Skip per ottenere gli stessi obiettivi su qualsiasi IEnumerable, ma l'intera raccolta verrà ordinata in questo processo.

+0

Mi chiedo se, nel caso in cui 'OrderBy' sia implementato funzionalmente (ad es. Per merge sort), la combinazione di' take/skip' plus * lazy evaluation * non eseguirà in realtà un ** partial ** sort come richiesto. 'head (sort list))' in Haskell - per esempio - è un approccio O (n) valido per trovare il minimo di una lista. Qualche suggerimento? – Dario

+0

@Dario: In teoria, ~ potrebbe ~, ma l'implementazione corrente no. –

+0

Sarebbe stato divertente però :) – Dario

Problemi correlati