Return Top X Results From Linq To Objects Query in Order
PREVIOUSLY: In this question someone told me how to use CompareTo to return surnames within a particular range ordered alphabetically using LINQ to Objects.
The rest of my question, which seems to have missed the initial question asking feeding frenzy, actually arose after I tested this solution. In the previous eaxample I had a list of names:
Adams Bentham Bickford Gillies Kelly Moore Peters Rutherford Smith Taylor Williams
And I wanted to be able to query them for all the names between Gillies and Moore for example and get:
Gillies Kelly Moore
This is all well and good if you want every single solitary name inbetween the goalposts returned no matter what. The problem comes in when you have a huge quantity of surnames and you want a maximum of four of the names between Gillies and Taylor returned in alphabetical order, for example.
So the desired output is:
Gillies Kelly Moore Peters
However just returning four results between Gillies and Taylor could return Kelly, Peters, Smith and Taylor, or Gillies, Moore, Rutherford and Smith. Basically, the query takes you at your word and just selects any old four between the goalposts.
So, how can I get the top 4 results alphabetically. I could write a second query of course and return a subset and then select from within that... but shouldn't there be a way to integrate this behaviour into the initial query?
I've tried a couple of things with OrderBy and so far they just don't work. So it's over to you guys.
EDIT: for those two of you who've suggested using "take" I already am using take. It doesn't "take" in order, even if you use OrderBy or at least it doesn't in my query. Here it is:
var allIDs = (from cust in dc.orders
join item in dc.order_items on cust.orderid equals item.orderid
join del in dc.deliveries on cust.deliveryid equals del.deliveryid
join dt in dc.deliverytypes on del.deliverytype equals dt.deliverytypeid
开发者_运维知识库 where eventcode == item.itemcode
&& dt.description == "Secure Post"
&& (cust.status == "OK" || cust.status == "PB")
&& cust.surname.CompareTo(surfrom ?? " ") >= 0
&& cust.surname.CompareTo(surto ?? "zzz") <= 0
&& (cust.trackingcode == null ? false : (bool)cust.trackingcode)==false
orderby cust.surname, cust.initials, cust.ordercode
select cust.orderid).Distinct().Take(ordermax);
That just returns four names from between the names you've selected, not a specific four names.
From your edit it looks like you're doing the orderby and distinct in a strange order:
This works for me (where "allMyNames" is just a List<string>).
var ofInterest = allMyNames
.Distinct()
.Where(x => x.CompareTo(from) >= 0 && x.CompareTo(to) <= 0)
.OrderBy(x => x)
.Take(4);
I'm much happier using the extension form of LINQ :)
Use the "Take" LINQ method to take the first 4 records:
var query = (from name in originalList
where name.CompareTo(fromName) >= 0 && name.CompareTo(toName) <= 0
orderby name
select name).Take(4);
GetNames(...).Take(4);
Will take the first four items in the enumerable.
精彩评论