2
私は、製品の大きなリストから関連する製品の上位N
要素を選択する必要があります。 これまでのところ、以下のコードがあり、完全に動作します。上位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
に添加しました。
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();
は基本的に、私はそれがRating
上ご注文前だったのと同じ方法でリストを順序し直すLINQ Join
を使用します。
最初に追加した商品は他の商品よりも選択した商品との類似性が高いので、この方法でやりたいと思います。
私はここに二つの質問があります。
- は、再注文返されたリストに良い方法はありますか?
- 製品間の関係を処理する優れた設計はありますか? (私は、ツリー構造の実装を考えていた。オブジェクトのナビゲーションと検索がより速くなるでしょう。だから)
良いアイデアを使用します!!! 2番目の質問に対する提案はありますか? – Mhd
2番目の質問には簡単な答えはありません。このような構造をデータベースに保持しているのであれば、おそらくそれを実行した方法が唯一可能な方法です。しかし、あるソースからメモリ構造だけを構築している場合、おそらく共有された 'HashSet'を(処理中にビルドしたものに似ていますが、' this'も含めて)各製品に格納することができますより良い。 –