C# 选择前N个元素并记住出现时间';s指令

C# 选择前N个元素并记住出现时间';s指令,c#,C#,我需要从大量产品列表中选择相关产品的顶级N元素。 到目前为止,我有下面的代码,它工作得很好 class Product { public string Name; public double Rating; public List<Product> RelatedProducts; public List<Product> GetTopRelatedProducts(int N) { var relatedSet

我需要从大量产品列表中选择相关产品的顶级
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();
    }
}
如果
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();
基本上,我使用
linqjoin
对列表重新排序,方法与在
Rating
上排序之前相同

我想这样做,因为第一次添加的产品比其他产品与所选产品有更多的相似性

我这里有两个问题:

  • 有没有更好的方法对返回的列表重新排序
  • 是否有更好的设计来处理产品之间的关系?(我正在考虑实现一个树状结构,这样对象导航和检索会更快)
  • 有没有更好的方法对返回的列表重新排序

    您可以简单地将
    relatedSet
    与前N个相关的重新排序集一起使用,因为
    Intersect
    根据项目在第一个序列中的顺序生成项目

    所以不是

    return relatedSet.OrderByDescending(x => x.Rating).Take(N).ToList();
    
    你会用

    return relatedSet.Intersect(relatedSet.OrderByDescending(x => x.Rating).Take(N)).ToList();
    

    你的第二个问题没有简单的答案。如果您要在数据库中持久化这种结构,那么您这样做的方式可能是唯一可能的方式。但是如果您只是从某个源构建一个内存结构,那么在每个产品中存储一个共享的
    HashSet
    (与我们在处理过程中构建的产品类似,但也包括
    this
    )可能会更好。
    return relatedSet.Intersect(relatedSet.OrderByDescending(x => x.Rating).Take(N)).ToList();