[英]How do I .OrderBy() and .Take(x) this LINQ query?
下面的LINQ查詢工作正常,但我需要對其進行一些調整。
我希望所有recordId所組合文件中的記錄(客戶編號),然后通過排序,按降序排列,日期。 我正在進行分組,日期按降序排列。 現在,調整開始了。
我希望組按recordId升序排列。 目前,似乎按日期對組進行了排序。 我嘗試在.GroupBy之后添加.OrderBy,但根本無法正常工作。
最后,我想。取(x)的記錄,其中x是依賴於一些其他因素。 基本上,。取(X)將返回最近期的X個記錄。 我想在不同的地方放置。取(x)和我沒有得到正確的結果。
var recipients = File.ReadAllLines(path)
.Select (record => record.Split('|'))
.Select (tokens => new
{
FirstName = tokens[2],
LastName = tokens[4],
recordId = tokens[13],
date = Convert.ToDateTime(tokens[17])
}
)
.OrderByDescending (m => m.date)
.GroupBy (m => m.recordId)
.Dump();
編輯#1 - 的recordId不是唯一的。 可能/將有多個具有相同recordId的記錄。 recordId實際上是一個客戶編號。
輸出將與姓,名,日期和的recordId一個結果。 根據多個因素,每個recordId返回1至5條記錄。
編輯#2-.Take(x)用於recordId。 每個recordId可以具有多個行。 現在,讓我們假設我想要每個recordId的最新日期。 (按日期降序選擇top(1))
編輯#3 -
以下查詢生成以下結果。 請注意,每個recordId在輸出中僅產生1行(可以),並且它看起來是最近的日期。 我還沒有徹底檢查。
現在,如何按recordId升序排序?
var recipients = File.ReadAllLines(path)
.Select (record => record.Split('|'))
.Select (tokens => new
{
FirstName = tokens[2],
LastName = tokens[4],
recordId = Convert.ToInt32(tokens[13]),
date = Convert.ToDateTime(tokens[17])
}
)
.GroupBy (m => m.recordId)
.OrderByDescending (m => m.Max (x => x.date ) )
.Select (m => m.First () )
.Dump();
FirstName LastName recordId date
X X 2531334 3/11/2011 12:00:00 AM
X X 1443809 10/18/2001 12:00:00 AM
X X 2570897 3/10/2011 12:00:00 AM
X X 1960526 3/10/2011 12:00:00 AM
X X 2475293 3/10/2011 12:00:00 AM
X X 2601783 3/10/2011 12:00:00 AM
X X 2581844 3/6/2011 12:00:00 AM
X X 1773430 3/3/2011 12:00:00 AM
X X 1723271 2/4/2003 12:00:00 AM
X X 1341886 2/28/2011 12:00:00 AM
X X 1427818 11/15/1986 12:00:00 AM
您不能輕易按不屬於“分組依據”字段的字段進行排序。 您會獲得每個組的列表。 這意味着,您將獲得每個recordId
的date
列表。
最近日期排序:
.GroupBy (m => m.recordId)
// take the most recent date in the group
.OrderByDescending (m => m.Max(x => x.date))
.SelectMany(x => x.First
將Take
的部分是另外一個問題。 您可以僅將Take(x)
添加到表達式中,然后獲得此數量的組。
編輯:
對於一種select top(1)
:
.GroupBy (m => m.recordId)
// take the most recent date in the group
.OrderByDescending (m => m.Max(x => x.date))
// take the first of each group, which is the most recent
.Select(x => x.First())
// you got the most recent record of each recordId
// and you can take a certain number of it.
.Take(x);
之前我在回答中打斷過,根據現在的問題,您將不再需要它:
// create a separate group for each unique date and recordId
.GroupBy (m => m.date, m => m.recordId)
.OrderByDescending (m => m.Key)
只需添加
.OrderBy( g=> g.Key);
分組之后。 這將按RecordId升序排列您的groupings
。
最后,我想。取(x)的記錄,其中x是依賴於一些其他因素。 基本上,。取(X)將返回最近期的X個記錄。
如果您按日期表示“最新”,那么為什么要首先按RecordId分組-只是按日期降序排列:
..
.OrderByDescending (m => m.date)
.Take(x)
.Dump();
如果您只想按分組確定的順序獲得前x個記錄,則可以執行以下操作:
...
.GroupBy (m => m.recordId)
.SelectMany(s => s)
.Take(x)
.Dump();
這似乎與您的其他問題非常相似- 使用LINQ讀取已刪除的文件
我完全不相信您要在此處使用Group-我相信相反,您想要使用OrderBy和ThenBy-類似:
var recipients = File.ReadAllLines(path)
.Select (record => record.Split('|'))
.Select (tokens => new
{
FirstName = tokens[2],
LastName = tokens[4],
recordId = tokens[13],
date = Convert.ToDateTime(tokens[17])
}
)
.OrderBy (m => m.recordId)
.ThenByDescending (m => m.date)
.Dump();
對於簡單的Take ...,您可以僅在Dump()
之前添加此.Take(N)
Dump()
但是,我不確定這是您要找的東西嗎? 你能澄清你的問題嗎?
如果您想要每個組的前三個,那么我認為您需要使用如下嵌套查詢:
var recipients = File.ReadAllLines(path)
.Select(record => record.Split('|'))
.Select(tokens => new
{
FirstName = tokens[2],
LastName = tokens[4],
RecordId = tokens[13],
Date = Convert.ToDateTime(tokens[17])
}
)
.GroupBy(m => m.RecordId)
.Select(grouped => new
{
Id = grouped.Key,
First3 = grouped.OrderByDescending(x => x.Date).Take(3)
}
.Dump();
如果要將其展平到記錄列表中,則可以使用SelectMany:
var recipients = var recipients = File.ReadAllLines(path)
.Select(record => record.Split('|'))
.Select(tokens => new
{
FirstName = tokens[2],
LastName = tokens[4],
RecordId = tokens[13],
Date = Convert.ToDateTime(tokens[17])
}
)
.GroupBy(m => m.RecordId)
.Select(grouped => grouped.OrderByDescending(x => x.Date).Take(3))
.SelectMany(item => item)
.Dump();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.