我需要从大量产品中选择相关产品的顶级N
元素。
到目前为止,我有下面的代码,它的工作完美。
class Product
{
public string Name;
public double Rating;
public List<Product> RelatedProducts;
public List<Product> GetTopRelatedProducts(int N)
{
var relatedSet = new HashSet<Product>();
var relatedListQueue = new Queue<List<Product>>();
if (RelatedProducts != null && RelatedProducts.Count > 0)
relatedListQueue.Enqueue(RelatedProducts);
while (relatedListQueue.Count > 0)
{
var relatedList = relatedListQueue.Dequeue();
foreach (var product in relatedList)
{
if (product != this && relatedSet.Add(product) && product.RelatedProducts != null && product.RelatedProducts.Count > 0)
relatedListQueue.Enqueue(product.RelatedProducts);
}
}
return relatedSet.OrderByDescending(x => x.Rating).Take(N).OrderBy(/*How to order by occurrence here? */).ToList();
}
}
现在,我希望GetTopRelatedProducts
方法记住热门N
产品的发生顺序。首先添加到HashSet
的产品将在返回列表的开头。
例如,如果我有这种情况:
//...
relatedSet.Add(new Product(){Name="A", Rating=3});
relatedSet.Add(new Product(){Name="B", Rating=4});
relatedSet.Add(new Product(){Name="C", Rating=5});
//...
如果N = 2
,则该方法应返回:B,C
而不是C,B
,因为B
首先添加到HashSet
。
所以我将方法中的return语句改为:
var relatedSetCopy = relatedSet.ToList();
return (from p in relatedSet.OrderByDescending(x => x.Rate).Take(N)
join c in relatedSetCopy on p.Name equals c.Name
let index = relatedSetCopy.IndexOf(c)
orderby index
select p).ToList();
基本上,我使用LINQ Join
按照Rating
上的排序方式重新排序列表。
我想这样做是因为首次添加的产品与所选产品的相似性高于其他产品。
我在这里有两个问题:
答案 0 :(得分:3)
有没有更好的方法来重新订购返回的列表?
您可以简单地Intersect relatedSet
与前N个相关的重新排序集,因为Intersect
会根据第一个序列中的顺序生成项目。
所以而不是
return relatedSet.OrderByDescending(x => x.Rating).Take(N).ToList();
你会用
return relatedSet.Intersect(relatedSet.OrderByDescending(x => x.Rating).Take(N)).ToList();