我正在处理一个充满项目之间相似性的矩阵 . 我将这些保存为数据库中的对象列表 . Similarity对象如下所示:
public class Similarity
{
public virtual Guid MatrixId { get; set; } //The id of the matrix the similarity is in
public virtual Guid FirstIndex { get; set; } //The id of the item of the left side of the matrix
public virtual Guid SecondIndex { get; set; } //The id of the item of the top side of the matrix
public virtual double Similarity { get; set; } //The similarity
}
用户可以查看这些项目 . 我想检索用户已审阅的项目列表'similar' . 问题是我可以 FirstIndex
的id在 FirstIndex
或 SecondIndex
中 . 我写了一些代码,它可以完成我想要的,但我想知道这是否可以在1个语句中实现 .
var itemsNotReviewed = Similarities.Where(x => !itemsReviewed.Contains(x.SecondIndex))
.GroupBy(x => x.SecondIndex)
.ToList();
itemsNotReviewed.AddRange(Similarities.Where(x => !itemsReviewed.Contains(x.FirstIndex))
.GroupBy(x => x.FirstIndex)
.ToList());
其中 itemsReviewed
是用户已审阅的项目的guid列表,其中 Similarities
是与用户已审阅的项目类似的所有项目的列表 . 我用这个函数检索该列表:
return (from Row in _context.SimilarityMatrix
where itemIds.Contains(Row.FirstIndex) || itemIds.Contains(Row.SecondIndex)
select Row)
.Distinct()
.ToList();
其中 itemIds
是用户已审阅的项目的guid列表 .
有没有办法根据Where子句分组第一个或第二个索引?
如果我要详细说明,请告诉我!
3 回答
根据我的理解,你有一个
Similarity
的清单,保证包含FirstIndex
或SecondIndex
itemsReviewed
列表中包含FirstIndex
或SecondIndex
的项目 . 并且你需要使用itemsReviewed
中包含的索引 not 来获取元素(如果有的话)(由于第一个约束它可能只是其中一个)并且由该索引分组 .上面简单的LINQ翻译就像这样:
但它包含重复的
itemsReviewed.Contains
检查,这会对性能产生负面影响 .所以更好的变体是引入中间变量,最简单的方法是查询语法和
let
子句:我会改变你原始列表的来源:
这样您只需按匹配索引进行分组 .
您可能希望在动态对象之后转换为Similarity类,或者只是更改类以包含匹配索引 .
您可以通过以下方式将它们转换为您的相似类型:
关于什么
let语句引入了一个存储boolean的新的tempoary变量 . 您当然也可以内联其他功能:
如果您想使用非LINQ语法,您可能需要引入一些匿名类型: