Dictionary<Key, <Quality,Item>>
品質とアイテムの関係を追跡している があります。Qualities はオブジェクト タイプで、Items はオブジェクト タイプです。その他の場所には、有効な Quality と有効な Items のリストがあります。アイテムには、常に複数の品質の固定リストがあります。プログラムの状態に応じて、0 を含む任意の数の品質を保持できます。
現在、これを解決するための私の失敗した戦略の 1 つとして、Item オブジェクトはリスト内の独自の品質も追跡します。これが役立つかどうかはわかりませんが、今のところ役に立たないことは確かであり、役に立たないことが判明した場合はおそらく取り除かれます。
少なくとも 1 つの品質を正常に共有する一意のアイテムのペアを収集する LINQ 自己結合が既にあります。
var r = from KeyValuePair<int, Tuple<Quality, Item>> virtQ2I_1
in QualitiesToItems
join KeyValuePair<int, Tuple<Quality, Item>> virtQ2I_2
in QualitiesToItems
on virtQ2I_1.Value.Item1.name equals virtQ2I_2.Value.Item1.name
where (virtQ2I_1.Value.Item2.name != virtQ2I_2.Value.Item2.name)
select new List<Item>
{
virtQ2I_1.Value.Item2,
virtQ2I_2.Value.Item2
};
その後、別のディクショナリを使用して、<ItemA, ItemB> が <ItemB, ItemA> と同じと見なされる小さなげっぷをクリーンアップします。
必要なもの:トリプレット内の少なくとも 1 つの他のアイテムと少なくとも 1 つの品質を共有する固有のアイテムの各トリプレットのリスト。毛むくじゃらの複雑な問題:トリプルの 3 番目の項目は、既存の共有品質の 1 つだけを共有することはできません。それは関係に何か新しいものをもたらさなければなりません。そして、数百の項目のリストからすぐに結果を取得する必要があります。既存のソリューションは、この最後の要件を満たしていません。
例:
- ItemA は毛むくじゃらで、金髪で、四本足で、訓練を受けています
- アイテムBは毛皮、ナナカマド、6本足、訓練済み
- アイテム C は、羽毛、青、2 本足、訓練済みです。
ItemD は Scaled、Rowan、Slithers、および Untrained です
ItemA と ItemB はすでに有効なペアとして選択されており、Furry と Trained の品質を共有しています。(もちろん、B:D は別の有効なペアであり、A:C と B:C も同様です)
ItemA、ItemB、および ItemC は有効なトリプレットを作成しません。A:B は既にトレーニング済みであり、ItemC は ItemA または ItemB と他に共通点がないためです。A:B:C は A:B と同じ品質リストを持っているため、C は「過剰」または「重複」として拒否されます。
ItemA、ItemB、および ItemD は、ItemD が Rowan と ItemB の周りにペアを形成するため、有効なトリプレットを作成します。A:B:D の結果は Furry、Rowan、Trained です。返された結果のリストに入れるには、A:B:D の組み合わせが必要です。
ペアを取得する方法から、適切な時間内に数百のアイテムで機能する方法でトリプレットを取得する必要がある方法まで、問題が発生しています。
2 つのアイテム間で共有される品質を検索するメソッドを作成し、それを新しい LINQ クエリで使用したとき、私は非常に賢いと思っていましたが、結果は... 10 点以上のアイテムで使用すると非常に遅くなり、私のコンピューターは、これが実行されるいくつかのマシンと比較して圧倒的です.
var r = from KeyValuePair<int, Tuple<Quality, Item>> virtQ2I_1
in QualitiesToItems
join KeyValuePair<int, Tuple<Quality, Item>> virtQ2I_2
in QualitiesToItems
on virtQ2I_1.Value.Item1.name equals virtQ2I_2.Value.Item1.name
join KeyValuePair<int, Tuple<Quality, Item>> virtQ2I_3
in QualitiesToItems
on virtQ2I_2.Value.Item1.name equals virtQ2I_3.Value.Item1.name
where (virtQ2I_1.Value.Item2.name != virtQ2I_2.Value.Item2.name &&
virtQ2I_1.Value.Item2.name != virtQ2I_3.Value.Item2.name &&
virtQ2I_2.Value.Item2.name != virtQ2I_3.Value.Item2.name &&
Item.SharedQualities(this, new Item[2] { virtQ2I_1.Value.Item2, virtQ2I_2.Value.Item2 }).Count !=
Item.SharedQualities(this, new Item[3] { virtQ2I_1.Value.Item2, virtQ2I_2.Value.Item2, virtQ2I_3.Value.Item2 }).Count)
select new List<Item>
{
virtQ2I_1.Value.Item2,
virtQ2I_2.Value.Item2,
virtQ2I_3.Value.Item2
};
だから:これはうまくいきましたが、私は好きではありません。クエリの途中で関数呼び出し (および新しい項目配列) を純粋な LINQ に置き換える方法はありますか? あるに違いない。