C# 如何将项目按顺序插入列表?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12172162/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 22:20:28  来源:igfitidea点击:

How to insert item into list in order?

c#sortinginsert

提问by Jerry

I have a List of DateTimeOffsetobjects, and I want to insert new ones into the list in order.

我有一个DateTimeOffset对象列表,我想按顺序将新对象插入列表中。

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

Sorry, need to update my 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

Also, how to put DateTimeOffsetas the parameter of .OrderBy()?

另外,如何将其DateTimeOffset作为参数.OrderBy()

I have also tried:

我也试过:

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

However, it returns this error message,

但是,它返回此错误消息,

Cannot implicitly convert type 'System.Linq.IOrderedEnumerable' to 'System.Collections.Gerneric.List'. An explicit conversion exist (are you missing a cast?)

无法将类型“System.Linq.IOrderedEnumerable”隐式转换为“System.Collections.Gerneric.List”。存在显式转换(您是否缺少演员表?)

采纳答案by Tommy Grovnes

Modify your LINQ, add ToList() at the end:

修改你的 LINQ,在最后添加 ToList():

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

Alternatively assign the sorted list to another variable

或者将排序列表分配给另一个变量

var sortedList = from s in ....

回答by techfun

To insert item to a specific index

将项目插入到特定索引

you can use:

您可以使用:

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

To sort the collection you can use linq:

要对集合进行排序,您可以使用 linq:

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

回答by levi

You can use Insert(index,object)after finding index you want.

您可以Insert(index,object)在找到您想要的索引后使用。

回答by L.B

Assuming your list is already sorted in ascending order

假设您的列表已经按升序排序

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

回答by Tim Schmelter

With .NET 4 you can use the new SortedSet<T>otherwise you're stuck with the key-value collection SortedList.

使用 .NET 4,你可以使用新的,SortedSet<T>否则你会被键值集合卡住SortedList

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

Note: The SortedSet<T>class does not accept duplicate elements. If item is already in the set, this method returns false and does not throw an exception.

注意:SortedSet<T>该类不接受重复元素。如果 item 已经在集合中,则此方法返回 false 并且不会抛出异常。

If duplicates are allowed you can use a List<DateTimeOffset>and use it's Sortmethod.

如果允许重复,您可以使用 aList<DateTimeOffset>并使用它的Sort方法。

回答by noseratio

A slightly improved version of @L.B.'s answerfor edge cases:

@LB对边缘情况的回答的略微改进版本:

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

回答by peeyush singh

very simple, after adding data into list

非常简单,将数据添加到列表后

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

回答by kjhf

I took @Noseratio's answerand reworked and combined it with @Jeppe's answer from hereto get a function that works for Collections that implement IList (I needed it for an ObservableCollection of Paths) and type that does not implement IComparable.

我把@ Noseratio的回答和返工,并@了Jeppe距离的回答结合它在这里得到一个函数,实现IList的作品集(我需要它的路径的一个ObservableCollection)和类型不实现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 IList<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 IList<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 = 0;
            if (collection is List<T> list)
            {
                index = list.BinarySearch(item, comparerFunction);
            }
            else if (collection is T[] arr)
            {
                index = Array.BinarySearch(arr, item, comparerFunction);
            }
            else
            {
                for (int i = 0; i < collection.Count; i++)
                {
                    if (comparerFunction.Compare(collection[i], item) <= 0)
                    {
                        // If the item is the same or before, then the insertion point is here.
                        index = i;
                        break;
                    }

                    // Otherwise loop. We're already tested the last element for greater than count.
                }
            }

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