我有一个Dictionary<Key, <Quality,Item>>
正在跟踪质量和项目之间的关系。质量是一种对象类型,项目是一种对象类型,在其他地方我有有效质量和有效项目的列表。物品有一个固定的品质列表,总是不止一个。质量可以由任意数量的项目持有,包括 0,具体取决于程序的状态。
目前,项目对象还在列表中跟踪它们自己的质量,这是我解决此问题的失败策略之一。我不知道这是否有用,它现在肯定对我没有帮助,如果证明没用,可能会被淘汰。
我已经有一个 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> 相同的小打嗝。
需要什么:每个三元组的唯一项目的列表,这些项目至少与三元组中的至少一个其他项目共享一个品质。毛茸茸的大并发症:三元组中的第三项不能只共享现有的共享品质之一;它必须给这段关系带来一些新的东西。而且我需要从几百个项目的列表中快速获得结果——我现有的解决方案不满足最后一个要求。
例子:
- ItemA 是毛茸茸的、金发的、四足的、训练有素的
- ItemB 是毛茸茸的、罗文的、六足的、训练有素的
- ItemC 是有羽毛的、蓝色的、两条腿的、训练有素的
ItemD 是 Scaled、Rowan、Slithers 和未经训练的
ItemA 和 ItemB 已经被选为有效的一对,具有 Furry 和 Trained 的品质。(B:D 当然是另一个有效的配对,A:C 和 B:C 也是如此)
ItemA、ItemB 和 ItemC 不构成有效的三元组,因为 A:B 已经训练过了,并且 ItemC 与 ItemA 或 ItemB 没有其他共同点;A:B:C 与 A:B 具有相同的 Qualities 列表,因此 C 被视为“多余”或“冗余”而被拒绝。
ItemA、ItemB 和 ItemD 构成一个有效的三元组,因为 ItemD 与 ItemB 在 Rowan 周围形成一对。A:B:D 的结果是 Furry、Rowan、Trained... 我需要 A:B:D 的组合进入我的返回结果列表。
从我获得我的双胞胎的方式到我需要以一种在合理的时间内处理数百件物品的方式获得我的三胞胎的方式,我遇到了问题。
当我编写一个方法来查找两个项目之间的共享品质并将其用于我的新 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
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 替换我的函数调用(和新项目数组)中间查询?必须有。