我有一个玩家列表,每个玩家都包含技能等级列表。 我想要做的是根据与特定搜索列表匹配的评级来命令这些玩家。
以下是四名球员的例子:
List<Skill> skillsA = new List<Skill>();
List<Skill> skillsB = new List<Skill>();
List<Skill> skillsC = new List<Skill>();
List<Skill> skillsD = new List<Skill>();
skillsA.Add(new Skill() { Name = "Speed", Value = 1 });
skillsA.Add(new Skill() { Name = "Agility", Value = 5 });
skillsA.Add(new Skill() { Name = "Strength", Value = 3 });
skillsA.Add(new Skill() { Name = "Endurance", Value = 4 });
skillsB.Add(new Skill() { Name = "Speed", Value = 5 });
skillsB.Add(new Skill() { Name = "Agility", Value = 2 });
skillsB.Add(new Skill() { Name = "Strength", Value = 1 });
skillsB.Add(new Skill() { Name = "Endurance", Value = 3 });
skillsC.Add(new Skill() { Name = "Speed", Value = 5 });
skillsC.Add(new Skill() { Name = "Agility", Value = 3 });
skillsC.Add(new Skill() { Name = "Strength", Value = 2 });
skillsC.Add(new Skill() { Name = "Endurance", Value = 2 });
skillsD.Add(new Skill() { Name = "Speed", Value = 1 });
skillsD.Add(new Skill() { Name = "Agility", Value = 2 });
skillsD.Add(new Skill() { Name = "Strength", Value = 5 });
skillsD.Add(new Skill() { Name = "Endurance", Value = 4 });
Player A = new Player() { Skills = skillsA };
Player B = new Player() { Skills = skillsB };
Player C = new Player() { Skills = skillsC };
Player D = new Player() { Skills = skillsD };
这将是我与之比较的搜索列表:
List<Skill> matchSkill = new List<Skill>();
matchSkill.Add(new Skill() { Name = "Speed", Value = 5 });
matchSkill.Add(new Skill() { Name = "Agility", Value = 2 });
matchSkill.Add(new Skill() { Name = "Strength", Value = 1 });
matchSkill.Add(new Skill() { Name = "Endurance", Value = 1 });
SkillSearch SkillSearch = new SkillSearch() { Skills = matchSkill };
我应该找回订购PlayerB,PlayerC,PlayerD,PlayerA
的玩家列表技能列表将始终具有相同的大小和相同的顺序。技能总是从1-5。我尝试使用绝对值比较值之间的差异。例如,如果搜索是针对a(3)2,那么4将是比1或5更接近的匹配。
简而言之,如果您只是将它们视为数字数组,那么您将拥有:
search = { 5, 2, 1, 1}
playerb = { 5, 2, 1, 3} : difference {0,0,0,2} (2 total)
playerc = { 5, 3, 2, 2} : difference {0,1,1,1} (3 total)
playerd = { 1, 2, 5, 4} : difference {4,0,4,3} (11 total)
playera = { 1, 5, 3, 4} : difference {4,3,2,3} (12 total)
我如何使用C#订购?我更喜欢linq的结果。我只是不确定如何订购这些产品。
答案 0 :(得分:3)
假设上课:
public class Skill
{
public string Name { get; set; }
public int Value { get; set; }
}
public class Player
{
public string Name { get; set; }
public ICollection<Skill> Skills { get; set; }
}
您可以使用collection initializers替换List<T>.Add
来电的序列:
Player[] players = new Player[]
{
new Player
{
Name = "A",
Skills = new Skill[]
{
new Skill { Name = "Speed", Value = 1 },
new Skill { Name = "Agility", Value = 5 },
new Skill { Name = "Strength", Value = 3 },
new Skill { Name = "Endurance", Value = 4 },
}
},
new Player
{
Name = "B",
Skills = new Skill[]
{
new Skill { Name = "Speed", Value = 5 },
new Skill { Name = "Agility", Value = 2 },
new Skill { Name = "Strength", Value = 1 },
new Skill { Name = "Endurance", Value = 3 },
}
},
new Player
{
Name = "C",
Skills = new Skill[]
{
new Skill { Name = "Speed", Value = 5 },
new Skill { Name = "Agility", Value = 3 },
new Skill { Name = "Strength", Value = 2 },
new Skill { Name = "Endurance", Value = 2 },
}
},
new Player
{
Name = "D",
Skills = new Skill[]
{
new Skill { Name = "Speed", Value = 1 },
new Skill { Name = "Agility", Value = 2 },
new Skill { Name = "Strength", Value = 5 },
new Skill { Name = "Endurance", Value = 4 },
}
}
};
Skill[] matchSkills = new Skill[]
{
new Skill { Name = "Speed", Value = 5 },
new Skill { Name = "Agility", Value = 2 },
new Skill { Name = "Strength", Value = 1 },
new Skill { Name = "Endurance", Value = 1 },
};
接下来,您应该为Dictionary<string, Skill>
集合构建matchSkills
;这将允许您通过名称快速查找技能:
var matchSkillsDictionary = matchSkills.ToDictionary(matchSkill => matchSkill.Name);
最后,您可以使用LINQ OrderBy
操作按照技能差异总和的降序对玩家进行排序。我们将使用两个中间函数来帮助保持清晰:
Func<Skill, int> getSkillDiff = skill => Math.Abs(skill.Value - matchSkillsDictionary[skill.Name].Value);
Func<Player, int> getPlayerDiff = player => player.Skills.Sum(getSkillDiff);
IEnumerable<Player> orderedPlayers = players.OrderBy(getPlayerDiff);
答案 1 :(得分:3)
试试这个:
players.OrderBy(player => player.Skills.Zip(matchSkills, (pl, sr) => Math.Abs(pl.Value - sr.Value)).Sum())
玩家是阵列{A,B,C,D}。
通过道格拉斯修复了丢失的“.Skills”和“.Value”部分。
答案 2 :(得分:2)
回复给Dmitry Polyanitsa:
我认为这就是你的意思:
players.OrderBy(player => player.Skills.Zip(matchSkills, (pl, sr) => Math.Abs(pl.Value - sr.Value)).Sum());
但是,您假设所有玩家(以及匹配集)的技能总是按相同的顺序排列。如果一个玩家定义Speed, Agility, Strength, Endurance
,则另一个玩家无法定义Agility, Speed, Strength, Endurance
。
修改:实际上,您的假设是正确的。问题是:“技能列表总是大小相同,顺序相同。”我很抱歉错过了。
在这种情况下,您的解决方案可能比我的原始提案更有效,因为它避免了名称查找的开销。