private static void Main()
{
var accounts = new List<Account>()
{
new Account { PrimaryId = 1, SecondaryId = 10 },
new Account { PrimaryId = 1, SecondaryId = 12 }
};
}
public class Account
{
public int PrimaryId { get; set; }
public IList<int> SecondaryIds { get; set; }
public int SecondaryId { get; set; }
}
假設我有上面的代碼,我想按 PrimaryId 分組并將 SecondaryId 合并到 SecondaryIds 中。
例如:
// PrimaryId = 1
// SecondaryIds = 10, 12
怎樣才能實作呢?
到目前為止我做到了
var rs = accounts.GroupBy(g => g.PrimaryId == 1)
.Select(s => new Accounts
{ PrimaryId = 1, SecondaryIds = new List<int>() { /*???*/ } });
uj5u.com熱心網友回復:
我會做什么,也許
LINQGroupBy在其最簡單的形式中,采用一個 lambda,它回傳應分組的 Key。.GroupBy(a => a.PrimaryId). 它產生類似于“串列串列”的東西,其中內部串列中的所有內容都具有相同的鍵。
如果你做了那個分組,你可以像這樣探索它:
var listOfLists = accounts.GroupBy(a => a.PrimaryId);
foreach(var innerList in listOfLists){
Console.WriteLine("Key is: " innerList.Key);
foreach(Account account in innerList)
Console.WriteLine("Sid is: " account.SecondaryId);
}
因此,它有效地將您的 Account 物件放入 a 之類的東西中List<List<Account>>,除了內部串列有一個Key屬性可以告訴您內部串列中的帳戶都共享什么共同值(PrimaryId)
有一個 GroupBy 的擴展形式,它接受第二個引數“什么專案,可能來自原始物件,你想放入內部串列?”,我們可以像這樣使用它:
.GroupBy(a => a.PrimaryId, a => a.SecondaryId)
這將創建類似 a 的內容List<List<int>>,因為它只是將 SecondaryId 拉出并將其放入內部串列中,而不是整個帳戶物件。這很好,因為您仍然可以從中獲取 PrimaryId,Key并且 Account 中沒有其他任何內容
實際上,甚至還有另一種形式的 GroupBy 帶有第三個引數,它將獲取生成的“串列串列”中的每個專案,并允許你用它做一些事情。
.GroupBy(
a => a.PrimaryId, //derive the key
a => a.SecondaryId, //derive the innerList
(key, innerList) => new Account { PrimaryId = key, SecondaryIds = innerList.ToList() }
)
您可以將第三個引數視為.Select()您在 groupby 末尾放置的。它略有不同,并且可能更易于使用,因為“密鑰”和“具有該密鑰的事物串列”之間有明顯的區別
因此,第一個引數(key,是分組鍵(PrimaryID),第二個引數innerList)是具有該分組鍵的所有SecondaryIds 的串列。我們可以使用這兩個資訊來創建一個Account設定了 Primary 和 SecondaryIds 的新物件
我在評論中提到,在一個物件中有一個 SecondaryId 以及它們的串列是很奇怪的。我知道你為什么這樣做,但如果你想洗掉 SecondaryId 單數并只保留串列,groupby會略有變化:
.GroupBy(
a => a.PrimaryId,
a => a.SecondaryId.First(), //take the only item
(key, innerList) => new Account { PrimaryId = key, SecondaryIds = innerList.ToList() }
)
這將能夠處理輔助 ID 的單個專案串列,例如:
var accounts = new List<Account>()
{
new Account { PrimaryId = 1, SecondaryIds = new(){10} },
new Account { PrimaryId = 1, SecondaryIds = new(){12} }
};
看看你的嘗試:
var rs = accounts.GroupBy(g => g.PrimaryId == 1)
.Select(s => new Accounts
{ PrimaryId = 1, SecondaryIds = new List<int>() { /*???*/ } });
Doing .GroupBy(g => g.PrimaryId == 1) will group by an assessment of whether the PrimaryId is 1 or not. It won't filter anything to "just ID 1" - essentially anything that was PrimaryId 1 would go in one inner list, and everything else would go in another. The Key of the inner list would be a bool. If your accounts list only contained Account objects with Primary ID 1 then all would be fine. It'd go a bit haywire if it didn't
.Select(s => new Accounts
{ PrimaryId = 1, SecondaryIds = new List<int>() { /*???*/ } });
Your GroupBy() with one argument has produced something like a List<List<Account>>, so it means s is the inner list. It's actually an IGrouping<Account> which is like a list of Account objects but with that extra Key property that tells you what all the items in the grouping have in common.
This means that, because this .Select is giving you s and s is a list of Account, and you want just the SecondaryId out of each account in that list, you need another Select, this time on s to pull just the SecondaryId out of each account within it:
.Select(s => new Accounts
{
PrimaryId = 1,
SecondaryIds = s.Select(acc => acc.SecondaryId)
});
and then you want to call ToList() on that Select
.Select(s => new Accounts
{
PrimaryId = 1,
SecondaryIds = s.Select(acc => acc.SecondaryId).ToList()
});
If I was doing that way I'd do:
.GroupBy(a => a.PrimaryId)
.Select(g => new Accounts
{
PrimaryId = g.Key,
SecondaryIds = g.Select(acc => acc.SecondaryId).ToList()
});
But the 3 argument GroupBy is a bit cleaner..
uj5u.com熱心網友回復:
使用.GroupBy()后跟時.Select(),您需要在分組專案中向下鉆取一層:
var rs = accounts
.GroupBy(a => a.PrimaryId)
.Select(gr => new Account {
PrimaryId = gr.Key,
SecondaryIds = gr.Select(account => account.SecondaryId).ToList()
});
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/427147.html
上一篇:查詢哈希表鍵LINQ運算式C#
