2012-08-29 57 views
15

¿Alguien podría enseñarme cómo insertar elementos en la lista en orden en C#?¿Cómo insertar un elemento en la lista en orden?

Tengo una lista de objetos DateTimeOffset, y quiero insertar nuevos en la lista en orden.

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

lo siento, necesito actualizar mi pregunta.

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 

Podría alguien por favor me ayude a poner DateTimeOffset como el parámetro de .OrderBy()?

También probé

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

Sin embargo, devuelve este mensaje de error,

No se puede convertir implícitamente el tipo 'System.Linq.IOrderedEnumerable' a 'System.Collections.Gerneric.List'. Una conversión explícita existe (¿falta una fundición?)

+4

¿No puedes ordenar tu lista cuando sea necesario o utilizar SortedList? –

+0

'Lista ' es colección * ordered *. ¿Desea * ordenar *? – adatapost

+1

¿De qué "orden" está hablando aquí? –

Respuesta

5

? Modifica LINQ, añadir ToList() al final:

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

asignar Como alternativa, la lista ordenada a otra variable

var sortedList = from s in .... 
1

Para insertar elemento a un índice específico

que puede utilizar:

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

Para ordenar la colección se puede utilizar LINQ:

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

¿Por qué no ordenar utilizando la extensión '.OrderBy()' –

+0

Sí, Ash Burlaczenko que también podemos hacer. Estoy acostumbrado a escribir grandes consultas en linq. Es por eso que escribí la consulta anterior, que fue lo primero que se me vino a la mente. Pero estoy de acuerdo contigo Gracias. – techfun

+0

No hay una sobrecarga de 'List .Add' que toma un índice. Creo que te refieres a ['List .Insert'] (http://msdn.microsoft.com/en-us/library/sey5k5z4 (v = vs.100) .aspx). –

0

Puede buscar Insert(index,object) después de encontrar el índice que desea.

+0

dime ordenar para escribir más – levi

46

Asumiendo que su lista ya está ordenada en orden ascendente

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

¿Puedes explicar tu código? Si no saben cómo insertar en una lista, dudo que sabrán qué '~ index' lo hace. –

+0

@AshBurlaczenko, tienes razón, pero el contexto de la pregunta parece haber cambiado después de ~ 1 hora, respondí y soy demasiado flojo para eso. –

+12

** De MSDN **: Valor de retorno El índice basado en cero del artículo en la lista ordenada , si se encuentra el artículo; de lo contrario, un número negativo que es el complemento bit a bit del índice del siguiente elemento que es más grande que el elemento o, si no hay un elemento más grande, el complemento bit a bit de Count. –

7

Con .NET 4 se puede utilizar la nueva SortedSet<T> de lo contrario se pegan con la recogida de llaves valor SortedList.

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

Nota: La clase SortedSet<T> no acepta elementos duplicados. Si el artículo ya está en el conjunto, este método devuelve falso y no lanza una excepción.

Si se permiten duplicados, puede usar un List<DateTimeOffset> y usar su método Sort.

19

Una versión ligeramente mejorada del @L.B.'s answer para casos extremos:

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

Este fragmento me consiguió una mejora del rendimiento del 1000% en un caso en el que no pude usar SortedSet <> y tuve que repetir varias veces .Sort() a List. – Nebu

1

muy simple, después de agregar datos en li st

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

Tomé @Noseratio's answer y vuelta a trabajar y lo combinó con @ respuesta de Jeppe de here para obtener una función que funciona para colecciones (lo necesitaba para un ObservableCollection de Caminos) y el tipo que no 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()' creará otra colección que es más costosa que la búsqueda lineal, es decir, 'collection.IndexOf()' –

Cuestiones relacionadas