【发布时间】:2016-02-09 14:23:40
【问题描述】:
我有一个List 类型的元素
public class FriendList
{
public List<string> friends { get; set; } // List of friends names
public DateTime timestamp { get; set; } // date/time on the data file
}
我需要一个程序来获取由timestamp 排序的前 2 个(然后用它们做一些其他的事情)。所以我开始写的是
public void CompareLastTwo ( )
{
if ( this._fhist.Count < 2 )
{
Console.WriteLine("Need at least two instances of Facebook profile data in the Data folder");
}
FriendList latest, secondLatest;
if ( this._fhist[0].timestamp > this._fhist[1].timestamp )
{
latest = this._fhist[0];
secondLatest = this._fhist[1];
}
else
{
latest = this._fhist[1];
secondLatest = this._fhist[0];
}
for ( int i = 2, n = this._fhist.Count; i < n; ++i )
{
if ( this._fhist[i].timestamp > latest.timestamp )
{
secondLatest = latest;
latest = this._fhist[i];
}
else if ( this._fhist[i].timestamp > secondLatest.timestamp && this._fhist[i].timestamp <= latest.timestamp )
{
secondLatest = this._fhist[i];
}
}
// ...
}
但后来我通过查看How to get first N elements of a list in C#? 意识到我可以做到
List<FriendList> latestTwoFriendLists = this._fhist.OrderBy(L => L.timestamp).Take(2);
哪个更紧凑,但 是否同样高效????或者等式右边的计算过程是否在Takeing first 2之前得到一个完整的有序列表?
【问题讨论】:
-
好吧,从逻辑上讲,如果您希望前两项成为“最低”两项,则必须先进行排序。
-
@Rob 不,你可以像我一样通过集合一次迭代找到最低的两个
-
嗯,是的,但是您仍在迭代整个集合,
OrderBy也是这样做的。OrderBy.Take是延迟执行的,所以虽然OrderBy确实会迭代整个集合,但它不会创建新的有序列表。 -
@Rob 我会假设
OrderBy对集合进行快速排序,这意味着它不仅仅是对集合进行一次迭代 -
@Rob 由
OrderBy完成的常规排序总是 O(n * log(n)),选择“top-k”(其中 k 是固定的,不取决于 n)是 O (n) - 见 en.wikipedia.org/wiki/Category:Selection_algorithms - 像 QuickSelect。
标签: c# .net linq optimization