web-dev-qa-db-fra.com

Comment insérer un élément dans la liste dans l'ordre?

J'ai une liste d'objets DateTimeOffset et je souhaite en insérer de nouveaux dans la liste, dans l'ordre.

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

Désolé, besoin de mettre à jour ma question.

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

Aussi, comment mettre DateTimeOffset comme paramètre de .OrderBy()?

J'ai aussi essayé:

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

Cependant, il renvoie ce message d'erreur,

Impossible de convertir implicitement le type 'System.Linq.IOrderedEnumerable' en 'System.Collections.Gerneric.List'. Une conversion explicite existe (manque-t-il un casting?)

20
Jerry

Modifiez votre LINQ, ajoutez ToList () à la fin:

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

Vous pouvez également affecter la liste triée à une autre variable.

var sortedList = from s in ....
5
Tommy Grovnes

En supposant que votre liste est déjà triée par ordre croissant

var index = TimeList.BinarySearch(dateTimeOffset);
if (index < 0) index = ~index;
TimeList.Insert(index, dateTimeOffset);
56
L.B

Une version légèrement améliorée de la réponse de @ L.B. pour les cas Edge:

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);
    }
}
26
noseratio

Avec .NET 4, vous pouvez utiliser le nouveau SortedSet<T> sinon vous êtes bloqué avec la collection clé-valeur SortedList

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

Remarque: La classe SortedSet<T> n'accepte pas les éléments en double. Si item est déjà dans l'ensemble, cette méthode retourne false et ne lève pas d'exception. 

Si les doublons sont autorisés, vous pouvez utiliser un List<DateTimeOffset> et utiliser sa méthode Sort .

9
Rango

très simple, .__ après l'ajout de données dans la liste

list.OrderBy(a => a.ColumnName).ToList();
1
peeyush singh

Pour insérer un élément dans un index spécifique

vous pouvez utiliser:

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

Pour trier la collection, vous pouvez utiliser linq:

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

Vous pouvez utiliser Insert(index,object) après avoir trouvé l'index souhaité.

0
levi

J'ai pris la réponse de @ Noseratio et l'ai retravaillée et combinée avec la réponse de @ Jeppe de ici Pour obtenir une fonction qui fonctionne pour Collections (j'en avais besoin pour une collection Observable de chemins) et un type qui ne fonctionne pas implémenter 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);
      }
    }
0
kjhf