我正在尝试对这个复杂的对象进行排序:
Order _sut = new Order
{
OrderDataArray = new[]
{
new OrderData
{
OrderHeaderArray = new[]
{
new OrderHeader
{
SequenceNumber = 1,
OrderPositionArray = new[]
{
new OrderPositions
{
LineNumber = 3
},
new OrderPositions
{
LineNumber = 2
},
new OrderPositions
{
LineNumber = 1
}
}
}
}
}
}
};
使用代码:
[Fact]
public void Sorts_By_Sequence_Number()
{
var ordered = _sut.OrderDataArray
.OrderBy(o => o.OrderHeaderArray
.OrderBy(a => a.OrderPositionArray
.OrderBy(p => p.LineNumber)))
.ToArray();
_sut.OrderDataArray = ordered;
OutputHelper(_sut);
}
我不明白为什么这不起作用,这意味着排序例程只保留LineNumber
对象的初始顺序。我用OrderBy
尝试了各种各样的东西,但看起来它没有排序。
感谢您的回复,两者都是正确的。我已经接受了poke的响应,因为它提供了有关OrderBy方法内部工作的更详细信息。基本上我在循环中错过了赋值,我试图一次对所有对象进行排序。
答案 0 :(得分:2)
您应该考虑OrderBy
的作用。它按照您在lambda表达式中确定的值对集合进行排序,然后返回一个可枚举的。
你的外线电话有利于此:
_sut.OrderDataArray.OrderBy(o => something).ToArray();
您按某种方式排序,然后将结果转换为(然后排序的)数组。这里有两件事情重要:首先,至少在你的例子中,OrderDataArray
中只有一个对象,所以没有发生任何排序。其次,它取决于something
这些对象如何排序的返回值。
那么在那种情况下,something
是什么?它是以下内容:
o.OrderHeaderArray.OrderBy(a => somethingElse)
所以无论somethingElse
如何,这又回归了什么?一个IEnumerable<OrderHeader>
。多个枚举如何相互比较?它们不具有可比性;并且他们特别不会根据他们的内容告诉您有关订单的任何信息(您必须首先枚举它)。基本上,你通过“别的东西”订购OrderHeaderArray
,使用不会告诉你任何订单的结果作为订购OrderDataArray
的关键。然后,您将已排序的OrderHeaderArray
扔掉。
你使用OrderPositionArray
更深入地执行一个级别,这也不会做任何有用的事情。唯一真正有用的排序发生在OrderPositionArray
本身,但结果再次丢弃。
现在,如果你想订购你的结构,你应该通过将排序的结构重新分配到数组来正确地进行。因此,在某些时候,您必须执行以下操作:
a.OrderPositionArray = a.OrderPositionArray.OrderBy(p => p.LineNumber).ToArray();
但是除了OrderPositionArray
本身和OrderHeader
之外,你真的没有任何可以排序的东西(因为你不能按照子集合的顺序对集合进行真正的排序)。所以你可以这样解决它:
foreach (OrderData data in _sut.OrderDataArray)
{
foreach (OrderHeader header in data.OrderHeaderArray)
{
header.OrderPositionArray = header.OrderPositionArray.OrderBy(p => p.LineNumber).ToArray();
}
data.OrderHeaderArray = data.OrderHeaderArray.OrderBy(h => h.SequenceNumber).ToArray();
}
除了Linq之外,您还可以对数组进行就地排序,这可能会因为您没有创建新的内部数组而使它更好一些:
var c = Comparer<int>.Default;
foreach (OrderData data in _sut.OrderDataArray)
{
foreach (OrderHeader header in data.OrderHeaderArray)
{
Array.Sort(header.OrderPositionArray, new Comparison<OrderPositions>((x, y) => c.Compare(x.LineNumber, y.LineNumber)));
}
Array.Sort(data.OrderHeaderArray, new Comparison<OrderHeader>((x, y) => c.Compare(x.SequenceNumber, y.SequenceNumber)));
}
答案 1 :(得分:0)
在这里,
var ordered = _sut.OrderDataArray.OrderBy(o => ...
期望Func<OrderData, TKey>
,并且将通过比较此函数执行的结果对值进行排序。
同时,您传递另一个OrderBy
的结果,即IOrderedEnumerable
。它根本没有多大意义。
为了对所有嵌套集合进行排序,您可以执行以下操作:
foreach (var orderData in _sut.OrderDataArray)
{
foreach (var orderHeader in orderData.OrderHeaderArray)
{
orderHeader.OrderPositionArray = orderHeader.OrderPositionArray
.OrderBy(x => x.LineNumber).ToArray();
}
orderData.OrderHeaderArray = orderData.OrderHeaderArray
.OrderBy(x => x.SequenceNumber).ToArray();
}
_sut.OrderDataArray = _sut.OrderDataArray
.OrderBy(x => ...).ToArray();
按照项目“OrderPositionArray
对每个LineNumber
项目进行排序。”
它按标题'OrderHeaderArray
对每个SequenceNumber
进行排序。
但是,目前还不清楚如何对_sut.OrderDataArray
进行排序 - 在示例中标记为x => ...
。
它没有可用于分类的可比性质。