LINQ GroupBy return 列表作为结果
LINQ GroupBy return List as result
我有一个包含事务对象的列表。我想要做的是在上述列表中找到具有相同 transaction.Buyer.UserID 的交易,并将它们组合成一个列表列表。
每个子列表项目将包含多个交易对象,其中 transaction.Buyer.UserID 相同。
我目前拥有的是:
var _ordersToCombine =
_transactions.GroupBy(transaction => transaction.Buyer.UserID).Select(transaction => transaction);
我的收获:
List<Transaction>:
Transaction { Buyer.UserID = "User1" ...}
Transaction { Buyer.UserID = "User2" ...}
Transaction { Buyer.UserID = "User1" ...}
Transaction { Buyer.UserID = "User3" ...}
Transaction { Buyer.UserID = "User4" ...}
Transaction { Buyer.UserID = "User3" ...}
我对 return 的期望是:
List<List<Transaction>>:
List<Transaction>:
Transaction { Buyer.UserID = "User1" ...}
Transaction { Buyer.UserID = "User1" ...}
List<Transaction>:
Transaction { Buyer.UserID = "User3" ...}
Transaction { Buyer.UserID = "User3" ...}
...并从主列表中删除这些交易,因此在本例中主列表将如下所示:
List<Transaction>:
Transaction { Buyer.UserID = "User2" ...}
Transaction { Buyer.UserID = "User4" ...}
Linq 对我来说是一个新概念,我正在努力理解。
不,你得到的是 IEnumerable<IGrouping<TKey, TSource>>
请参阅:MSDN Group By
所以基本上它是 returns 组列表。该组包含对其进行分组的键和属于该组的项目列表的元素
列表
- 第 1 组
- 组键
- 项目(您的对象列表)
- 第 2 组
- 组键
- 项目(您的对象列表)
试试这个:
var dic = _transactions.GroupBy(t => t.Buyer.UserID).ToDictionary(t => t.Key, t => t.ToList());
GroupBy returns一个
IEnumerable<IGrouping<TKey, TSource>>
每个 IGrouping<> 都包含组标准作为键,并且每个 IGrouping 都是可枚举的(您列出分组值)
因为,问题改变了:
不要在 GroupBy 委托中创建匿名类型(没有新的 {...})
相反,直接针对 属性(因为在内部,GroupBy 使用相等性对事物进行分组,并且由于您创建了一个新的匿名对象,所以不会有任何分组,因为每个新对象都是不同的)
.GroupBy(o => o.Buyer.UserID, o.ToList)
此外,
Select(p => p)
什么都不做,这是一个身份函数。没用。
如果你想要的是List of List,我觉得你可以直接用Dictionary。 (请参阅我的回答的第一部分)您可以像枚举列表一样枚举字典。其中 add/remove/replace 项。
返回的字典类型为:
Dictionary<int,List<Transactions>> dic =....
使用 Key = UserId,并且对于每个键,一个交易列表。
此外,它确实比列表的列表更快,因为您可以直接访问交易:
int userId = 42;
List<Transactions> transactions = dic[userId];
Group by in LINQ.
这里有您的查询的答案。
var results = transactions.GroupBy(p => p.Buyer.UserID,
(key, g) => new { UserID = key, Cars = g.ToList() });
如果我没理解错的话,
您有一个交易清单,
和列表的交易列表。
你需要对后者进行分组,
通过 userId,其中值将是对应于该用户的交易。
如果是这样的话,
我准备了一个可能有用的小样本。
祝你好运
public class Transaction
{
public Buyer Buyer { get; set; }
}
public class Buyer
{
public int UserID { get; set; }
}
[TestMethod]
public void Test()
{
var t1 = new Transaction { Buyer = new Buyer { UserID = 1 } };
var t2 = new Transaction { Buyer = new Buyer { UserID = 2 } };
var t3 = new Transaction { Buyer = new Buyer { UserID = 3 } };
var t4 = new Transaction { Buyer = new Buyer { UserID = 1 } };
var t5 = new Transaction { Buyer = new Buyer { UserID = 3 } };
var tList1 = new List<Transaction> { t1, t2, t3 };
var tList2 = new List<Transaction> { t4, t5 };
var tLists = new List<List<Transaction>> { tList1 , tList2};
var result = tLists.
SelectMany(o => o).
GroupBy(o => new
{
UserId = o.Buyer.UserID
},
(key, items) => new
{
UserId = key.UserId,
Transactions = items.Select(p => p).ToList()
}).
ToList();
}
这是作者编辑的更新解决方案:
var transactions = new List<Transaction>
{
new Transaction { Buyer = new Buyer { UserID = 1 } },
new Transaction { Buyer = new Buyer { UserID = 2 } },
new Transaction { Buyer = new Buyer { UserID = 3 } },
new Transaction { Buyer = new Buyer { UserID = 1 } },
new Transaction { Buyer = new Buyer { UserID = 3 } }
};
var result = transactions.
Select(o => o).
GroupBy(o => new
{
UserId = o.Buyer.UserID
},
(key, items) => new
{
//UserId = key.UserId,
Transactions = items.Select(p => p).ToList()
}).
ToList();
只需使用它进行分组:
var results = transactions
.GroupBy(p => p.Buyer.UserID)
.Where(x=>x.Count()>1)
.Select(x=> new List<Transaction>(x));
这应该会产生您的 List<List<Transaction>
以及来自主列表的重复用户。
LINQ 并不是在遍历集合时修改集合的真正正确工具。如果你真的需要它,请执行:
var results = transactions.ToList()
.GroupBy(p => p.Buyer.UserID)
.Where(x=>x.Count()>1)
.Select(x=>
{
foreach(var item in x)
transactions.Remove(item);
return new List<Transaction>(x);
});
请注意,已创建事务列表的副本以执行查询(transactions.ToList()
,并在原始列表上进行删除操作。希望对您有所帮助。
我有一个包含事务对象的列表。我想要做的是在上述列表中找到具有相同 transaction.Buyer.UserID 的交易,并将它们组合成一个列表列表。
每个子列表项目将包含多个交易对象,其中 transaction.Buyer.UserID 相同。
我目前拥有的是:
var _ordersToCombine =
_transactions.GroupBy(transaction => transaction.Buyer.UserID).Select(transaction => transaction);
我的收获:
List<Transaction>:
Transaction { Buyer.UserID = "User1" ...}
Transaction { Buyer.UserID = "User2" ...}
Transaction { Buyer.UserID = "User1" ...}
Transaction { Buyer.UserID = "User3" ...}
Transaction { Buyer.UserID = "User4" ...}
Transaction { Buyer.UserID = "User3" ...}
我对 return 的期望是:
List<List<Transaction>>:
List<Transaction>:
Transaction { Buyer.UserID = "User1" ...}
Transaction { Buyer.UserID = "User1" ...}
List<Transaction>:
Transaction { Buyer.UserID = "User3" ...}
Transaction { Buyer.UserID = "User3" ...}
...并从主列表中删除这些交易,因此在本例中主列表将如下所示:
List<Transaction>:
Transaction { Buyer.UserID = "User2" ...}
Transaction { Buyer.UserID = "User4" ...}
Linq 对我来说是一个新概念,我正在努力理解。
不,你得到的是 IEnumerable<IGrouping<TKey, TSource>>
请参阅:MSDN Group By
所以基本上它是 returns 组列表。该组包含对其进行分组的键和属于该组的项目列表的元素
列表
- 第 1 组
- 组键
- 项目(您的对象列表)
- 第 2 组
- 组键
- 项目(您的对象列表)
试试这个:
var dic = _transactions.GroupBy(t => t.Buyer.UserID).ToDictionary(t => t.Key, t => t.ToList());
GroupBy returns一个
IEnumerable<IGrouping<TKey, TSource>>
每个 IGrouping<> 都包含组标准作为键,并且每个 IGrouping 都是可枚举的(您列出分组值)
因为,问题改变了:
不要在 GroupBy 委托中创建匿名类型(没有新的 {...}) 相反,直接针对 属性(因为在内部,GroupBy 使用相等性对事物进行分组,并且由于您创建了一个新的匿名对象,所以不会有任何分组,因为每个新对象都是不同的)
.GroupBy(o => o.Buyer.UserID, o.ToList)
此外,
Select(p => p)
什么都不做,这是一个身份函数。没用。
如果你想要的是List of List,我觉得你可以直接用Dictionary。 (请参阅我的回答的第一部分)您可以像枚举列表一样枚举字典。其中 add/remove/replace 项。
返回的字典类型为:
Dictionary<int,List<Transactions>> dic =....
使用 Key = UserId,并且对于每个键,一个交易列表。 此外,它确实比列表的列表更快,因为您可以直接访问交易:
int userId = 42;
List<Transactions> transactions = dic[userId];
Group by in LINQ.
这里有您的查询的答案。
var results = transactions.GroupBy(p => p.Buyer.UserID,
(key, g) => new { UserID = key, Cars = g.ToList() });
如果我没理解错的话,
您有一个交易清单, 和列表的交易列表。
你需要对后者进行分组, 通过 userId,其中值将是对应于该用户的交易。
如果是这样的话, 我准备了一个可能有用的小样本。
祝你好运
public class Transaction
{
public Buyer Buyer { get; set; }
}
public class Buyer
{
public int UserID { get; set; }
}
[TestMethod]
public void Test()
{
var t1 = new Transaction { Buyer = new Buyer { UserID = 1 } };
var t2 = new Transaction { Buyer = new Buyer { UserID = 2 } };
var t3 = new Transaction { Buyer = new Buyer { UserID = 3 } };
var t4 = new Transaction { Buyer = new Buyer { UserID = 1 } };
var t5 = new Transaction { Buyer = new Buyer { UserID = 3 } };
var tList1 = new List<Transaction> { t1, t2, t3 };
var tList2 = new List<Transaction> { t4, t5 };
var tLists = new List<List<Transaction>> { tList1 , tList2};
var result = tLists.
SelectMany(o => o).
GroupBy(o => new
{
UserId = o.Buyer.UserID
},
(key, items) => new
{
UserId = key.UserId,
Transactions = items.Select(p => p).ToList()
}).
ToList();
}
这是作者编辑的更新解决方案:
var transactions = new List<Transaction>
{
new Transaction { Buyer = new Buyer { UserID = 1 } },
new Transaction { Buyer = new Buyer { UserID = 2 } },
new Transaction { Buyer = new Buyer { UserID = 3 } },
new Transaction { Buyer = new Buyer { UserID = 1 } },
new Transaction { Buyer = new Buyer { UserID = 3 } }
};
var result = transactions.
Select(o => o).
GroupBy(o => new
{
UserId = o.Buyer.UserID
},
(key, items) => new
{
//UserId = key.UserId,
Transactions = items.Select(p => p).ToList()
}).
ToList();
只需使用它进行分组:
var results = transactions
.GroupBy(p => p.Buyer.UserID)
.Where(x=>x.Count()>1)
.Select(x=> new List<Transaction>(x));
这应该会产生您的 List<List<Transaction>
以及来自主列表的重复用户。
LINQ 并不是在遍历集合时修改集合的真正正确工具。如果你真的需要它,请执行:
var results = transactions.ToList()
.GroupBy(p => p.Buyer.UserID)
.Where(x=>x.Count()>1)
.Select(x=>
{
foreach(var item in x)
transactions.Remove(item);
return new List<Transaction>(x);
});
请注意,已创建事务列表的副本以执行查询(transactions.ToList()
,并在原始列表上进行删除操作。希望对您有所帮助。