2012-08-29 12 views
15

Qualcuno potrebbe insegnarmi come inserire un elemento nell'elenco in ordine in C#?Come inserire un elemento nell'elenco in ordine?

Ho un elenco di oggetti DateTimeOffset e voglio inserirne di nuovi nell'elenco in ordine.

List<DateTimeOffset> TimeList = ... 
// determine the order before insert or add the new item 

Spiacente, è necessario aggiornare la mia domanda.

List<customizedClass> ItemList = ... 
//customizedClass contains DateTimeOffset object and other strings, int, etc. 

ItemList.Sort(); // this won't work until set data comparison with DateTimeOffset 
ItemList.OrderBy(); // this won't work until set data comparison with DateTimeOffset 

Qualcuno potrebbe aiutarmi a mettere DateTimeOffset come parametro di .OrderBy()?

Ho anche provato

ItemList = from s in ItemList 
      orderby s.PublishDate descending // .PublishDate is type DateTime 
      select s; 

Tuttavia, viene restituito questo messaggio di errore,

Impossibile convertire implicitamente il tipo 'System.Linq.IOrderedEnumerable' a 'System.Collections.Gerneric.List'. Una conversione esplicita esiste (Vi manca un cast?)

+4

Non è possibile ordinare l'elenco quando necessario o utilizzare SortedList? –

+0

'Lista ' è raccolta * ordinata'. Desideri * ordinare *? – adatapost

+1

Di quale "ordine" stai parlando qui? –

risposta

5

modificare il vostro LINQ, aggiungere ToList() alla fine:

ItemList = (from s in ItemList 
      orderby s.PublishDate descending 
      select s).ToList(); 

alternativa assegnare l'elenco ordinato ad un altro

var sortedList = from s in .... 
1

Per inserire elemento a un indice specifico

è possibile utilizzare:

DateTimeOffset dto; 

// Current time 
dto = DateTimeOffset.Now; 

//This will insert the item at first position 
TimeList.Insert(0,dto); 

//This will insert the item at last position 
TimeList.Add(dto); 

Per ordinare la raccolta è possibile utilizzare LINQ:

//This will sort the collection in ascending order 
List<DateTimeOffset> SortedCollection=from dt in TimeList select dt order by dt; 
+2

Perché non ordinare utilizzando l'estensione '. OrdderBy()' –

+0

Sì, Ash Burlaczenko che è anche che possiamo fare. Sono usato scrivere grandi interrogazioni in linq. Ecco perché ho scritto la domanda di cui sopra che è stato il primo pensiero che mi è venuto in mente. Ma sono d'accordo con te. Grazie. – techfun

+0

Non c'è sovraccarico di 'Lista .Add' che prende un indice. Penso che tu intenda ['List .Insert'] (http://msdn.microsoft.com/en-us/library/sey5k5z4 (v = vs.100) .aspx). –

0

È possibile utilizzare Insert(index,object) dopo aver trovato l'indice desiderato.

+0

dimmi l'ordine per scrivere di più – levi

46

Supponendo che la vostra lista è già ordinato in ordine crescente

var index = TimeList.BinarySearch(dateTimeOffset); 
if (index < 0) index = ~index; 
TimeList.Insert(index, dateTimeOffset); 
+3

Puoi spiegare il tuo codice? Se non sanno come inserirli in una lista dubito che sapranno cosa '~ index' fa. –

+0

@AshBurlaczenko, hai ragione, ma il contesto della domanda sembra essere stato cambiato dopo ~ 1 ora ho risposto e sono troppo pigro per questo. –

+12

** Da MSDN **: Valore restituito L'indice a base zero dell'articolo nell'Elenco ordinato , se l'elemento viene trovato; in caso contrario, un numero negativo è il complemento bit per bit dell'indice dell'elemento successivo che è più grande dell'elemento o, se non esiste un elemento più grande, il complemento bit per bit di Count. –

7

Con .NET 4 è possibile utilizzare la nuova SortedSet<T> altrimenti sei bloccato con la collezione di valori-chiave SortedList.

SortedSet<DateTimeOffset> TimeList = new SortedSet<DateTimeOffset>(); 
// add DateTimeOffsets here, they will be sorted initially 

Nota: La classe SortedSet<T> non accetta gli elementi duplicati. Se l'elemento è già nell'insieme, questo metodo restituisce false e non genera un'eccezione.

Se sono consentiti i duplicati, è possibile utilizzare uno List<DateTimeOffset> e utilizzare il suo metodo Sort.

19

Un leggermente migliorata versione variabile @L.B.'s answer per casi limite:

public static class ListExt 
{ 
    public static void AddSorted<T>(this List<T> @this, T item) where T: IComparable<T> 
    { 
     if (@this.Count == 0) 
     { 
      @this.Add(item); 
      return; 
     } 
     if (@this[@this.Count-1].CompareTo(item) <= 0) 
     { 
      @this.Add(item); 
      return; 
     } 
     if (@this[0].CompareTo(item) >= 0) 
     { 
      @this.Insert(0, item); 
      return; 
     } 
     int index = @this.BinarySearch(item); 
     if (index < 0) 
      index = ~index; 
     @this.Insert(index, item); 
    } 
} 
+2

Questo frammento mi ha dato un miglioramento delle prestazioni del 1000% in un caso in cui non potevo usare SortedSet <> e dovevo ripetutamente .Sort() un elenco. – Nebu

1

molto semplice, dopo l'aggiunta di dati in li st

list.OrderBy(a => a.ColumnName).ToList(); 
0

ho preso @Noseratio's answer e rielaborato e combinato con @ risposta di Jeppe da here per ottenere una funzione che lavora per Collezioni (ne avevo bisogno per un ObservableCollection di tracciati) e il tipo che non implementa IComparable.

/// <summary> 
    /// Inserts a new value into a sorted collection. 
    /// </summary> 
    /// <typeparam name="T">The type of collection values, where the type implements IComparable of itself</typeparam> 
    /// <param name="collection">The source collection</param> 
    /// <param name="item">The item being inserted</param> 
    public static void InsertSorted<T>(this Collection<T> collection, T item) where T : IComparable<T> 
    { 
     InsertSorted(collection, item, Comparer<T>.Create((x, y) => x.CompareTo(y))); 
    } 

    /// <summary> 
    /// Inserts a new value into a sorted collection. 
    /// </summary> 
    /// <typeparam name="T">The type of collection values</typeparam> 
    /// <param name="collection">The source collection</param> 
    /// <param name="item">The item being inserted</param> 
    /// <param name="ComparerFunction">An IComparer to comparer T values, e.g. Comparer&lt;T&gt;.Create((x, y) =&gt; (x.Property &lt; y.Property) ? -1 : (x.Property &gt; y.Property) ? 1 : 0)</param> 
    public static void InsertSorted<T>(this Collection<T> collection, T item, IComparer<T> ComparerFunction) 
    { 
     if (collection.Count == 0) 
     { 
     // Simple add 
     collection.Add(item); 
     } 
     else if (ComparerFunction.Compare(item, collection[collection.Count - 1]) >= 0) 
     { 
     // Add to the end as the item being added is greater than the last item by comparison. 
     collection.Add(item); 
     } 
     else if (ComparerFunction.Compare(item, collection[0]) <= 0) 
     { 
     // Add to the front as the item being added is less than the first item by comparison. 
     collection.Insert(0, item); 
     } 
     else 
     { 
     // Otherwise, search for the place to insert. 
     int index = Array.BinarySearch(collection.ToArray(), item, ComparerFunction); 
     if (index < 0) 
     { 
      // The zero-based index of item if item is found; 
      // otherwise, a negative number that is the bitwise complement of the index of the next element that is larger than item or, if there is no larger element, the bitwise complement of Count. 
      index = ~index; 
     } 
     collection.Insert(index, item); 
     } 
    } 
+1

'collection.ToArray()' creerà un'altra raccolta che è più costosa della ricerca lineare i.e. collection.IndexOf() ' –

Problemi correlati