【问题标题】:Insert an object in a list in chronological order [duplicate]按时间顺序在列表中插入对象[重复]
【发布时间】:2021-03-03 18:12:26
【问题描述】:

我有一个包含 DateTime 属性的对象列表。 使用DataPickerTimePicker,我创建了一个DateTime 对象,然后将其插入ObservableCollection<>。但是,我想根据DateTime 的时间顺序在列表中插入元素。如何找到合适的位置将其放入列表中?

 public class HumorDiary
 {
    public DateTime Dt { get; set; }
 }

HumorDiary obj= new HumorDiary();
obj.Dt= xx/xx/xxxx;

ObservableCollection<HumorDiary> listDiario = new ObservableCollection<HumorDiary>();
    
listDiario.Insert(Position????, obj);

【问题讨论】:

  • 只需在插入新对象后对列表进行排序
  • listDiario.OrderBy(x => x.Dt);没事吧?
  • 你为什么不试试看它是否有效?
  • 可比较的对象,例如 DateTimestring(在副本中)具有 CompareTo() 方法,而 IList&lt;T&gt; 集合(例如 ObservableCollection&lt;T&gt;)可以使用二进制搜索(虽然与List&lt;T&gt; 不同,ObservableCollection` 没有内置方法,它很简单,可以自己实现)。您可以进行二分搜索或插入排序,这两种方法都在重复项的答案中进行了描述。

标签: c# xamarin.forms


【解决方案1】:

(测试代码后编辑答案。)

您可以自己对列表进行排序。

listDario.Add(obj);
listDario = new ObservableCollection<HumorDiary>(listDario.OrderBy(x => x.Dt));

令我惊讶的是,这实际上并没有触发额外的CollectionChanged 事件。但是,请注意,这会创建一个新列表,并且附加到该列表的事件处理程序可能会被取消链接。我还要说它不是非常有效。如果您根本不需要事件功能,请改用SortedList&lt;TKey,TValue&gt;

您也可以编写如下所示的扩展方法,但它假定列表已经排序,因此您必须确保每次插入都使用它。

    public static void InsertByDate(this ObservableCollection<HumorDiary> source, HumorDiary obj)
    {
        int idx = 0;
        while (idx < source.Count() && source[idx].Dt <= obj.Dt) {
            idx += 1;
        }
        source.Insert(idx, obj);
    }

【讨论】:

    【解决方案2】:

    实现此目的的方法不止一种,但最简单的方法是使用OrderBymethod。这是一个例子:

            HumorDiary obj1 = new HumorDiary();
            obj1.Dt = DateTime.Now;
            HumorDiary obj2 = new HumorDiary();
            obj2.Dt = DateTime.Now.AddHours(1);
            HumorDiary obj3 = new HumorDiary();
            obj3.Dt = DateTime.Now.AddHours(5);
    
            ObservableCollection<HumorDiary> listDiario = new ObservableCollection<HumorDiary>();
    
            listDiario.Add(obj3);
            listDiario.Add(obj2);
            listDiario.Add(obj1);
    
            listDiario = new ObservableCollection<HumorDiary>(listDiario.OrderBy(obj => obj.Dt));
    

    请注意,您必须在订购后将 iorderedenumerable 强制转换为 ObservableCollection。

    【讨论】:

    • 这个答案完全忽略了使用ObservableCollection&lt;T&gt;的意义,即当集合发生变化时集合通知客户端代码。如果您只是要用一个全新的集合替换该集合,那么一开始就没有理由使用 observable 集合。
    • 哦,你是对的!谢谢指正!
    猜你喜欢
    • 2013-02-20
    • 2021-02-24
    • 1970-01-01
    • 2016-12-01
    • 1970-01-01
    • 2019-05-11
    • 1970-01-01
    • 1970-01-01
    • 2012-10-21
    相关资源
    最近更新 更多