Как вставить элемент в список по порядку?
У меня есть список объектов DateTimeOffset
, и я хочу вставить новые в список по порядку.
List<DateTimeOffset> TimeList = ...
// determine the order before insert or add the new item
Извините, нужно обновить мой вопрос.
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
Кроме того, как поставить DateTimeOffset
в качестве параметра .OrderBy()
?
Я также попробовал:
ItemList = from s in ItemList
orderby s.PublishDate descending // .PublishDate is type DateTime
select s;
Тем не менее, он возвращает это сообщение об ошибке,
Не удалось неявно преобразовать тип 'System.Linq.IOrderedEnumerable' в 'System.Collections.Gerneric.List'. Существует явное преобразование (вам не хватает приведения?)
Ответы
Ответ 1
Измените свой LINQ, добавьте ToList() в конец:
ItemList = (from s in ItemList
orderby s.PublishDate descending
select s).ToList();
Или назначьте отсортированный список другой переменной
var sortedList = from s in ....
Ответ 2
Предполагая, что ваш список уже отсортирован в порядке возрастания
var index = TimeList.BinarySearch(dateTimeOffset);
if (index < 0) index = ~index;
TimeList.Insert(index, dateTimeOffset);
Ответ 3
Несколько улучшенная версия @L.B. ответ для краевых случаев:
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);
}
}
Ответ 4
С .NET 4 вы можете использовать новый SortedSet<T>
, иначе вы застряли в коллекции значений ключа SortedList
.
SortedSet<DateTimeOffset> TimeList = new SortedSet<DateTimeOffset>();
// add DateTimeOffsets here, they will be sorted initially
Примечание. Класс SortedSet<T>
не принимает повторяющиеся элементы. Если элемент уже установлен, этот метод возвращает false и не генерирует исключение.
Если дубликаты разрешены, вы можете использовать List<DateTimeOffset>
и использовать его Sort
.
Ответ 5
Чтобы вставить элемент в определенный индекс
вы можете использовать:
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);
Для сортировки коллекции вы можете использовать linq:
//This will sort the collection in ascending order
List<DateTimeOffset> SortedCollection=from dt in TimeList select dt order by dt;
Ответ 6
очень просто,
после добавления данных в список
list.OrderBy(a => a.ColumnName).ToList();
Ответ 7
Вы можете использовать Insert(index,object)
после поиска нужного вам индекса.
Ответ 8
Я взял @Noseratio ответ и переработал и объединил его с ответом @Jeppe от здесь
для получения функции, которая работает для Collections (мне она нужна для ObservableCollection of Paths) и типа, который не реализует 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);
}
}