这种情况可能远比我想要的复杂得多,但无论如何我都是把它带出来的。这适用于游戏型设计。
此处的值是硬编码的,但在实际环境中情况并非如此。
基本上,有一些名为Interpreter
的类列表,其中包含在程序引擎中翻译其他内容的相应信息。这些有一个默认的“布局”,但在许多特殊情况下,需要覆盖一些。
一个解决方案是在每个列表中都包含每个实例(这是可行的,但我认为它是多余的,我认为存在更清晰的解决方案)相反,我想要“组合”它们,但能够指定属性用作“覆盖”。 (完整的源代码可以在pastie上找到。我会把它放在这里,但我被告知,放上那么多代码会阻止人们回答我的问题):http://www.pastie.org/1276064
public class Program
{
static void Main()
{
var traits = new List<Trait>
{
new Trait { Name = "Intellect" },
new Trait { Name = "Strength" },
new Trait { Name = "Constitution" }
};
var scores = new List<Score>
{
new Score { Name = "Beginner", Rank = 1 },
new Score { Name = "Adept", Rank = 2 },
new Score { Name = "Expert", Rank = 3 },
new Score { Name = "Master", Rank = 4 }
};
// one sheet will have defaults
var initial = new Sheet
{
Interpreters = new List<Interpreter>
{
new Interpreter
{
Trait = traits.Single( s => s.Name == "Intellect" ),
Score = scores.Single( s => s.Rank == 1 ),
Requirement = 10
},
new Interpreter
{
Trait = traits.Single( s => s.Name == "Intellect" ),
Score = scores.Single( s => s.Rank == 2 ),
Requirement = 20
},
new Interpreter
{
Trait = traits.Single( s => s.Name == "Intellect" ),
Score = scores.Single( s => s.Rank == 3 ),
Requirement = 30
}
}
};
// other sheets will override some or all of the default
var advanced = new Sheet
{
Interpreters = new List<Interpreter>
{
new Interpreter
{
Trait = traits.Single( s => s.Name == "Intellect" ),
Score = scores.Single( s => s.Rank == 2 ),
Requirement = 15
},
new Interpreter
{
Trait = traits.Single( s => s.Name == "Intellect" ),
Score = scores.Single( s => s.Rank == 4 ),
Requirement = 35
}
}
};
// combined sheet should have values of default, with the appropriately 'overridden' values of the advanced
}
在这种情况下,组合列表应该是......
[0]
Trait = Intellect,
Score = 1,
Requirement = 10
[1]
Trait = Intellect,
Score = 2,
Requirement = 15
[2]
Trait = Intellect,
Score = 3,
Requirement = 30
[3]
Trait = Intellect,
Score = 4,
Requirement = 35
我确实知道如何通过这个特定的实例来实现它。我可以简单地编写一个方法来检查分数的值等。但我想要一个更加基于约定的方法,我可以用更复杂的方式使用它。有没有人有任何想法?
答案 0 :(得分:1)
要获得您描述的结果,您可以使用以下方法:
Sheet Combine(Sheet initial, Sheet advanced)
{
Sheet result = new Sheet();
result.Interpreters = new List<Interpreter>(
initial.Interpreters.Select(i =>
advanced.Interpreters.SingleOrDefault(a => a.Score == i.Score) ?? i)
);
return result;
}
当一个Sheet
包含不同的Trait
s时,我可能有逻辑错误,但您没有指定如何组合它们。
此外,您的代码设计很奇怪。并非每个集合都必须是List<T>
。特别是在这种情况下,使用Dictionary<K,V>
比使用Single()
更干净(更快)。
修改强>
对于您的更新版本,我更喜欢基于List
的解决方案而不是LINQ:
Sheet Combine(Sheet initial, Sheet advanced)
{
var interpreters = new List<Interpreter>(initial.Interpreters);
foreach (var interpreter in advanced.Interpreters)
{
int index = interpreters.FindIndex(x => x.Score == interpreter.Score);
if (index < 0)
interpreters.Add(interpreter);
else
interpreters[index] = interpreter;
}
return new Sheet { Interpreters = interpreters };
}
编辑2
以下是您要求的LINQ解决方案:
Sheet Combine(Sheet initial, Sheet advanced)
{
var scores = initial.Interpreters.Select(i => i.Score)
.Concat(advanced.Interpreters.Select(i => i.Score))
.Distinct().OrderBy(i => i);
var interpreters = scores.Select(s =>
advanced.Interpreters.SingleOrDefault(i => i.Score == s)
?? initial.Interpreters.Single(i => i.Score == s));
return new Sheet { Interpreters = interpreters };
}