【问题标题】:Know if order is changed after calling List.Sort()?知道调用 List.Sort() 后顺序是否改变了吗?
【发布时间】:2017-02-10 23:29:54
【问题描述】:

例如,如果List 包含{1,2,3,4,5},则调用Sort() 不会改变任何内容。但是如果列表中包含{1,2,4,3,5},那么调用Sort() 会改变顺序。

有什么方法可以知道Sort() 是否改变了什么?该方法返回void

附言 实际上,我在发布此问题之前对此进行了测试。这个想法是x 是当前在y 之前的一个项目,所以如果它需要返回一个负值,就会发生交换。不幸的是,它不起作用……但是为什么?

class IntComp : IComparer<int>
{
    public int Compare(int x, int y)
    {
        var result = x - y;
        if (result < 0)
            _IsChanged = true;
        return result;
    }

    private bool _IsChanged = false;
    public bool IsChanged()
    {
        var result = _IsChanged;
        _IsChanged = false;
        return result;
    }
}

var list = new List<int>() {};
Random r = new Random();
for (int i = 0; i < 1000; i++)
{
    list.Add(r.Next());
}

var comparer = new IntComp();
Stopwatch w = new Stopwatch();
w.Start();
list.Sort(comparer);
w.Stop();
Debug.WriteLine(comparer.IsChanged() + ", " + w.Elapsed);
w.Restart();
list.Sort(comparer);
w.Stop();
Debug.WriteLine(comparer.IsChanged() + ", " + w.Elapsed);

【问题讨论】:

  • 我很想知道...你为什么想知道?
  • 如果订单没有改变,我不必更新UI。
  • 然后按照建议您在排序之前检测它是否已排序的答案。

标签: c#


【解决方案1】:

为什么不将原始列表与排序后的列表进行比较?

var tmp = new List<MyType>(myList);
list.Sort();

if(tmp.SequenceEquals(list))
{
    // both lists are equals so your list wasn´t modified by Sort
}

SequenceEquals 将检查您的两个列表是否在完全相同的顺序中具有相同的元素。

编辑:您还可以编写一个简单的方法来迭代您的列表并检查所有元素是否都大于它们的祖先。这应该是禁食的方式,并避免不必要的迭代和列表副本:

public bool IsOrdered<T>(this IEnumerable<T> src) where T: IComparable
{
    for(int i = 1; i < myList.Count; i++)
    {
        if(myList[i - 1].CompareTo(myList[i]) == 1) return false;
    }
    return true;
}

【讨论】:

  • 我希望有一种有效的方法。这需要创建一个新列表和 O(n) 比较。在内部必须有一个发生交换的点,Sort() 可以监视它并提供一种方法来知道它是否改变了任何东西。不过既然好像没有,那我就这样走吧。
  • @DamnVegetables 如果你真的想要一个好的解决方案,你可以阅读这个答案。
【解决方案2】:

如果你只想在内存中保留原始列表,你可以做的是首先检查列表是否is sorted。如果是,则不需要排序,因此没有改变;如果它没有排序,你可以排序它,然后你确定它已经改变了。

这样,您就不必创建列表的副本以供以后比较,因此可以节省一些内存。

【讨论】:

  • 您不会获得任何内存,因为检查列表是否已排序也会通过完全迭代来对列表进行排序。
  • @Fran 在示例中,IsOrdered 函数只接受一个列表。你不需要两个...
  • @Fran 您不会将该列表与任何其他列表进行比较。您将列表中的项目相互比较。答案也绝不需要点击链接即可获得答案;说这是一个链接唯一的答案是荒谬的。答案中显然有超出链接的内容。
  • @Servy - 恕我直言,链接的 SO 帖子有多个答案,而 L-4 似乎指的是一个非常具体的答案,而不是被接受的答案,这使得恕我直言,这令人困惑,因为这就是我的假设被提及。至少非链接唯一答案应该链接到所引用的答案或至少复制代码本身。不过,这只是我的看法……从表面上看……我猜 :(
  • @Fran 就像我说的,甚至没有必要(或理由,真的)点击链接。答案完全独立地回答了这个问题,并且恰好提供了一个补充链接,如果您想要更多的话。
猜你喜欢
  • 1970-01-01
  • 2010-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多