如何使用linq从列表字典中获取项目

时间:2012-09-07 14:33:06

标签: c# linq data-structures linq-to-objects

我真的不懂LINQ。我发现的每个例子都过于简化,以至于我不知道为什么你甚至会使用LINQ,或者太复杂以至于我需要知道LINQ如何工作才能理解它。

所以我想知道你是否以及如何使用LINQ ......在这个例子中假设你有一个玩家类列表,每个类里面都有一个能力列表。每种能力都有等级要求。如何使用LINQ为一组特定类选择所有等于或低于某个等级的能力?

Giveen这个数据:

  • 的Class1
    • Ability1 - Level 1
    • 能力2 - 等级5
    • 能力3 - 等级9
  • 的Class2
    • Ability4 - Level 1
    • Ability5 - Level 2
    • 能力6 - 等级6
  • Class3的
    • Ability7 - Level 2
    • Ability8 - Level 4
    • Ability9 - Level 6

我想要一份Class1&的所有能力列表5级或以下的Class3。结果应该是{Ability1,Ability2,Ability7,Ability8}。

public class Class1
{

  public class Ability
  {
    public string Name { get; set; }
    public int Level { get; set; }
  }

  public class PlayerClass
  {
    public string Name { get; set; }
    public List<Ability> Abilities { get; set; }
  }

  public List<PlayerClass> Classes { get; set; }

  public Class1()
  {
    PlayerClass oClass;

    Classes = new List<PlayerClass>();

    oClass = new PlayerClass();
    oClass.Name = "Class1";
    oClass.Abilities = new List<Ability>();
    oClass.Abilities.Add(new Ability() { Name = "Ability1", Level = 1 });
    oClass.Abilities.Add(new Ability() { Name = "Ability2", Level = 5 });
    oClass.Abilities.Add(new Ability() { Name = "Ability3", Level = 9 });
    Classes.Add(oClass);

    oClass = new PlayerClass();
    oClass.Name = "Class2";
    oClass.Abilities = new List<Ability>();
    oClass.Abilities.Add(new Ability() { Name = "Ability4", Level = 1 });
    oClass.Abilities.Add(new Ability() { Name = "Ability5", Level = 2 });
    oClass.Abilities.Add(new Ability() { Name = "Ability6", Level = 6 });
    Classes.Add(oClass);

    oClass = new PlayerClass();
    oClass.Name = "Class3";
    oClass.Abilities = new List<Ability>();
    oClass.Abilities.Add(new Ability() { Name = "Ability7", Level = 2 });
    oClass.Abilities.Add(new Ability() { Name = "Ability8", Level = 4 });
    oClass.Abilities.Add(new Ability() { Name = "Ability9", Level = 6 });
    Classes.Add(oClass);

    IEnumerable<Ability> Abilities = 
                   GetAbilitiesForClasses("Class1;Class3".Split(';'), 5);
    //Abilities should contain Ability1, Ability2, Ability7, Ability8
  }

  public IEnumerable<Ability> GetAbilitiesForClasses
       (string[] asClassNames, int iLevel)
  {
    // TODO: Use LINQ to return the abilities for the class names 
           //contained in asClassNames that are at or below level: iLevel
    return null;
  }
}

4 个答案:

答案 0 :(得分:3)

public IEnumerable<Ability> GetAbilitiesForClasses(string[] asClassNames, int iLevel)
{
    return Classes
           .Where(X => asClassNames.Contains(X.Name))
           .SelectMany(X => X.Abilities)
           .Where(X => X.Level <= iLevel)
           .ToList();
}

答案 1 :(得分:3)

假设您的播放器类由PlayerClass类表示,Abilities属性类型为IDictionary<string, int>

List<PlayerClass> classes = ...
var results =
    from c in classes
    where c.Name == "Class1" || c.Name == "Class2"
    from ab in c.Abilities // ab is of type KeyValuePair<string, int>
    where ab.Value <= 5
    select ab.Key;

但最好定义一个AbilityNameLevel属性; Abilities属性将是IList<Ability>

List<PlayerClass> classes = ...
var results =
    from c in classes
    where c.Name == "Class1" || c.Name == "Class2"
    from ab in c.Abilities
    where ab.Level <= 5
    select ab.Name;

答案 2 :(得分:1)

如果你只是存储能力,你可以将它们合并为一个结构,并拥有一个可以执行LINQ的类列表。

例如:

public List<AbilityClass> Abilities { get; set; }

LINQ:

 var level9Abilities = (from a in Abilities
                    where.Level == "Level 9"
                 // where a.Level > 9 (if Level is an int)
                  select a).ToList();


 foreach (var lvl in level9Abilities) {
      Console.WriteLine(lvl);
 }

答案 3 :(得分:1)

您可以使用SelectMany,假设:

 public class Class
{
    public List<Ability> Abilities { get; set; }
}

public class Ability
{
    public string Name { get; set; }
    public int Level { get; set; }
}

使用Linq:

var classes = new List<Class>() {class1, class3};

var output = classes.SelectMany(c => c.Abilities)
            .Where(a => a.Level <= 5);