C# 如何检查列表是否已排序?

C# 如何检查列表是否已排序?,c#,unit-testing,list,html-lists,C#,Unit Testing,List,Html Lists,我正在做一些单元测试,我想知道是否有任何方法可以测试一个列表是否按照它包含的对象的属性排序 现在我这样做,但我不喜欢,我想要一个更好的方式。谁能帮帮我吗 // (fill the list) List<StudyFeedItem> studyFeeds = Feeds.GetStudyFeeds(2120, DateTime.Today.AddDays(-200), 20); StudyFeedItem previous = studyFeeds.First();

我正在做一些单元测试,我想知道是否有任何方法可以测试一个列表是否按照它包含的对象的属性排序

现在我这样做,但我不喜欢,我想要一个更好的方式。谁能帮帮我吗

// (fill the list)
List<StudyFeedItem> studyFeeds = 
    Feeds.GetStudyFeeds(2120, DateTime.Today.AddDays(-200), 20);   

StudyFeedItem previous = studyFeeds.First();

foreach (StudyFeedItem item in studyFeeds)
{
    if (item != previous)
    {
        Assert.IsTrue(previous.Date > item.Date);
    }

    previous = item;
}
//(填写列表)
列出研究提要=
feed.getstudyfeed(2120,DateTime.Today.AddDays(-200),20);
StudyFeedItem previous=studyFeeds.First();
foreach(studyFeeds中的StudyFeedItem)
{
如果(项目!=上一个)
{
Assert.IsTrue(previous.Date>item.Date);
}
先前=项目;
}
那么:

var list = items.ToList();
for(int i = 1; i < list.Count; i++) {
    Assert.IsTrue(yourComparer.Compare(list[i - 1], list[i]) <= 0);
} 
var list=items.ToList();
for(int i=1;i
var list = items.ToList();
for(int i = 1; i < list.Count; i++) {
    Assert.IsTrue(yourComparer.Compare(list[i - 1], list[i]) <= 0);
} 
var list=items.ToList();
for(int i=1;iAssert.IsTrue(您的comparer.Compare(list[i-1],list[i])LINQ-y将使用一个单独的排序查询

var sorted = from item in items
 orderby item.Priority
 select item;

Assert.IsTrue(items.SequenceEquals(sorted));
类型推断意味着您需要一个

 where T : IHasPriority

但是,如果您有多个具有相同优先级的项,那么对于单元测试断言,您最好按照Jason的建议使用列表索引进行循环。

LINQ-y应该使用单独的排序查询

var sorted = from item in items
 orderby item.Priority
 select item;

Assert.IsTrue(items.SequenceEquals(sorted));
类型推断意味着您需要一个

 where T : IHasPriority

但是,如果您有多个具有相同优先级的项,那么对于单元测试断言,您最好按照Jason的建议循环使用列表索引。

无论如何,您必须遍历列表并确保这些项按您想要的顺序排列。由于项比较是自定义的,因此您可以查看create为此调用一个通用方法并传入一个比较函数-这与列表排序使用比较函数的方式相同。

您必须以这样或那样的方式遍历列表,并确保项目按您想要的顺序排列。由于项目比较是自定义的,您可以考虑为此和passi创建一个通用方法比较函数中的ng-与列表排序使用比较函数的方式相同。

var studyFeeds=Feeds.GetStudyFeeds(2120,DateTime.Today.AddDays(-200),20);
var studyFeeds = Feeds.GetStudyFeeds(2120, DateTime.Today.AddDays(-200), 20);
var orderedFeeds = studyFeeds.OrderBy(f => f.Date);

for (int i = 0; i < studyFeeds.Count; i++)
{
    Assert.AreEqual(orderedFeeds[i].Date, studyFeeds[i].Date);
}
var orderedFeeds=studyFeeds.OrderBy(f=>f.Date); for(int i=0;i
var studyFeeds=Feeds.GetStudyFeeds(2120,DateTime.Today.AddDays(-200),20);
var orderedFeeds=studyFeeds.OrderBy(f=>f.Date);
for(int i=0;i
if(studyFeeds.Length<2)
返回;
for(int i=1;istudyfeed[i].Date);
for
还没有死呢!

if(studyFeeds.Length<2)
返回;
for(int i=1;istudyfeed[i].Date);

for
还没有完全消亡!

如果您的单元测试框架有助手方法来断言集合的相等性,那么您应该能够执行以下操作(NUnit风格):


assert方法适用于任何
IEnumerable
,但当两个集合都是
IList
类型或“某物数组”类型时,断言失败时抛出的错误消息将包含第一个不合适元素的索引。

如果单元测试框架有助手方法来断言集合的相等性,您应该能够执行以下操作(NUnit风格):


assert方法适用于任何
IEnumerable
,但当两个集合的类型都是
IList
或“某物数组”时,assert失败时抛出的错误消息将包含第一个不合适元素的索引。

如果您使用的是MSTest,您可能需要查看一下

可能是在断言中使用的另一个有用的API

在这两种情况下,您都应该准备一个按预期顺序保存预期列表的列表,然后将该列表与结果进行比较

下面是一个例子:

var studyFeeds = Feeds.GetStudyFeeds(2120, DateTime.Today.AddDays(-200), 20);   
var expectedList = studyFeeds.OrderByDescending(x => x.Date);
Assert.IsTrue(expectedList.SequenceEqual(studyFeeds));

如果您正在使用MSTest,您可能需要查看

可能是在断言中使用的另一个有用的API

在这两种情况下,您都应该准备一个按预期顺序保存预期列表的列表,然后将该列表与结果进行比较

下面是一个例子:

var studyFeeds = Feeds.GetStudyFeeds(2120, DateTime.Today.AddDays(-200), 20);   
var expectedList = studyFeeds.OrderByDescending(x => x.Date);
Assert.IsTrue(expectedList.SequenceEqual(studyFeeds));

NET 4.0的一种方法是使用该方法压缩列表,使其自身偏移量为1,从而将列表中的每个项目与后续项目配对

var ordered = studyFeeds.Zip(studyFeeds.Skip(1), (a, b) => new { a, b })
                        .All(p => p.a.Date < p.b.Date);
var ordered=studyFeeds.Zip(studyFeeds.Skip(1),(a,b)=>new{a,b})
.全部(p=>p.a.Date
如果您使用的是框架的早期版本,则可以编写自己的Zip方法,而不会有太多麻烦,类似于以下内容(参数验证和枚举数的处理(如果适用)留给读者):

公共静态IEnumerable Zip(
这是第一次,
我数不清的秒,
Func选择器)
{
var e1=first.GetEnumerator();
var e2=second.GetEnumerator();
而(e1.MoveNext()&e2.MoveNext())//one&很重要
收益率返回选择器(e1.Current,e2.Current);
}

一种.NET 4.0方法是使用该方法将列表压缩到自身偏移量为1的位置,将列表中的每个项目与后续项目配对。然后,您可以检查每个配对的条件是否为真,例如

var ordered = studyFeeds.Zip(studyFeeds.Skip(1), (a, b) => new { a, b })
                        .All(p => p.a.Date < p.b.Date);
var ordered=studyFeeds.Zip(studyFeeds.Skip(1),(a,b)=>new{a,b})
.全部(p=>p.a.Date
如果您使用的是框架的早期版本,则可以编写自己的Zip方法,而不会有太多麻烦,类似于以下内容(参数验证和枚举数的处理(如果适用)留给读者):

公共静态IEnumerable Zip(
这是第一次,
我数不清的秒,
乐趣
Assert.That(collection, Is.Ordered.By("PropertyName"));
    public static bool IsAscendingOrder<T>(this IEnumerable<T> seq) where T : IComparable
    {
        var seqArray = seq as T[] ?? seq.ToArray();
        return !seqArray.Where((e, i) =>
            i < seqArray.Count() - 1 &&
            e.CompareTo(seqArray.ElementAt(i + 1)) >= 0).Any();
    }
Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreEqual(
  mylist.OrderBy((a) => a.SomeProperty).ToList(),
  mylist,
  "Not sorted.");
var ordered = studyFeeds.Zip(studyFeeds.Skip(1), (a, b) => new { a, b })
                        .All(p => p.a.Date <= p.b.Date);
var ordered = !studyFeeds.Zip(studyFeeds.Skip(1), (a, b) => a.Date <= b.Date)
                        .Contains(false);
public static bool IsAscendingOrder<T>(this IEnumerable<T> seq) where T : IComparable<T>
{
    var predecessor = default(T);
    var hasPredecessor = false;

    foreach(var x in seq)
    {
        if (hasPredecessor && predecessor.CompareTo(x) >= 0) return false;
        predecessor = x;
        hasPredecessor = true;
    }

    return true;
}
double[] score1 = new double[] { 12.2, 13.3, 5, 17.2, 2.2, 4.5 };
double[] score2 = new double[] { 2.2, 4.5, 5, 12.2, 13.3, 17.2 };

bool isordered1 = score1.Aggregate(double.MinValue,(accum,elem)=>elem>=accum?elem:double.MaxValue) < double.MaxValue;
bool isordered2 = score2.Aggregate(double.MinValue,(accum,elem)=>elem>=accum?elem:double.MaxValue) < double.MaxValue;

Console.WriteLine ("isordered1 {0}",isordered1);
Console.WriteLine ("isordered2 {0}",isordered2);
double[] score3 = new double[] { 12.2, 13.3, 5, 17.2, 2.2, 4.5 };
double[] score4 = new double[] { 2.2, 4.5, 5, 12.2, 13.3, 17.2 };

bool isordered3 = score3.Aggregate((double?)double.MinValue,(accum,elem)=>(elem>(accum??(double?)double.MaxValue).Value)?(double?)elem:(double?)null) !=null;
bool isordered4 = score4.Aggregate((double?)double.MinValue,(accum,elem)=>(elem>(accum??(double?)double.MaxValue).Value)?(double?)elem:(double?)null) !=null;

Console.WriteLine ("isordered3 {0}",isordered3);
Console.WriteLine ("isordered4 {0}",isordered4);
var isOrderedAscending = lJobsList.SequenceEqual(lJobsList.OrderBy(x => x));
var isOrderedDescending = lJobsList.SequenceEqual(lJobsList.OrderByDescending(x => x));
var orderedSequence = lJobsList.OrderBy(x => x)
                               .ToList();

var reversedOrderSequence = orderedSequence.AsEnumerable()
                                           .Reverse();

if (lJobsList.SequenceEqual(orderedSequence))
{
     // Ordered in ascending
}
else (lJobsList.SequenceEqual(reversedOrderSequence))
{
     // Ordered in descending
}
var asc = jobs.OrderBy(x => x);
var desc = jobs.OrderByDescending(x => x);
if (jobs.SequenceEqual(asc) || jobs.SequenceEquals(desc)) // ...
public static bool IsOrdered<T>(this IList<T> list, IComparer<T> comparer = null)
{
    if (comparer == null)
    {
        comparer = Comparer<T>.Default;
    }

    if (list.Count > 1)
    {
        for (int i = 1; i < list.Count; i++)
        {
            if (comparer.Compare(list[i - 1], list[i]) > 0)
            {
                return false;
            }
        }
    }
    return true;
}
public static System.ComponentModel.ListSortDirection? SortDirection<T>(this IEnumerable<T> items, Comparer<T> comparer = null)
{
    if (items == null) throw new ArgumentNullException("items");
    if (comparer == null) comparer = Comparer<T>.Default;

    bool ascendingOrder = true; bool descendingOrder = true;
    using (var e = items.GetEnumerator())
    {
        if (e.MoveNext())
        {
            T last = e.Current; // first item
            while (e.MoveNext())
            {
                int diff = comparer.Compare(last, e.Current);
                if (diff > 0)
                    ascendingOrder = false;
                else if (diff < 0)
                    descendingOrder = false;

                if (!ascendingOrder && !descendingOrder)
                    break;
                last = e.Current;
            }
        }
    }
    if (ascendingOrder)
        return System.ComponentModel.ListSortDirection.Ascending;
    else if (descendingOrder)
        return System.ComponentModel.ListSortDirection.Descending;
    else
        return null;
}
var items = new[] { 3, 2, 1, 1, 0 };
var sort = items.SortDirection();
Console.WriteLine("Is sorted? {0}, Direction: {1}", sort.HasValue, sort);
//Is sorted? True, Direction: Descending
enum Sort {
  Unsorted,
  Same,
  SortedAscending,
  SortedDescending
}
Sort GetSort<T>(IEnumerable<T> source, IComparer<T> comparer = null) {
  if (source == null)
    throw new ArgumentNullException(nameof(source));
  if (comparer == null)
    comparer = Comparer<T>.Default;

  using (var enumerator = source.GetEnumerator()) {
    if (!enumerator.MoveNext())
      return Sort.Same;
    Sort? result = null;
    var previousItem = enumerator.Current;
    while (enumerator.MoveNext()) {
      var nextItem = enumerator.Current;
      var comparison = comparer.Compare(previousItem, nextItem);
      if (comparison < 0) {
        if (result == Sort.SortedDescending)
          return Sort.Unsorted;
        result = Sort.SortedAscending;
      }
      else if (comparison > 0) {
        if (result == Sort.SortedAscending)
          return Sort.Unsorted;
        result = Sort.SortedDescending;
      }
    }
    return result ?? Sort.Same;
  }
}
public static bool IsAscending<T>(this IEnumerable<T> self, Func<T, T, int> compareTo) {
  var list = self as IList<T> ?? self.ToList();
  if (list.Count < 2) {
    return true;
  }
  T a = list[0];
  for (int i = 1; i < list.Count; i++) {
    T b = list[i];
    if (compareTo(a, b) > 0) {
      return false;
    }
    a = b;
  }
  return true;
}
bool result1 = Enumerable.Range(2, 10).IsAscending((a, b) => a.CompareTo(b));
var lst = new List<(int, string)> { (1, "b"), (2, "a"), (3, "s1"), (3, "s") };
bool result2 = lst.IsAscending((a, b) => {
  var cmp = a.Item1.CompareTo(b.Item1);
  if (cmp != 0) {
    return cmp;
  } else {
    return a.Item2.CompareTo(b.Item2);
  }
});