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?)
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 ....
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);
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);
}
}
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
.
très simple, .__ après l'ajout de données dans la liste
list.OrderBy(a => a.ColumnName).ToList();
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;
Vous pouvez utiliser Insert(index,object)
après avoir trouvé l'index souhaité.
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<T>.Create((x, y) => (x.Property < y.Property) ? -1 : (x.Property > 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);
}
}