2012-09-07 36 views
0

我不太了解LINQ。我发现每一个例子都过分简化,直到我不知道为什么你甚至会使用LINQ,或者太复杂,我需要已经知道LINQ如何工作以理解它。如何从linq列表字典中获取项目

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

Giveen这样的数据:

  • 的Class1
    • Ability1 - 第1级
    • Ability2 - 等级5
    • Ability3 - 等级9
  • 的Class2
    • Ability4 - 1级
    • Ability5 - 第2级
    • Ability6 - 等级6
  • Class3的
    • Ability7 - 第2级
    • Ability8 - 等级4
    • Ability9 - 等级6

我想要一个列表所有等级为5级或以下的Class1 & 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; 
    } 
} 
+6

如果您发布的defintions(在C#),你的类的一些样本数据,你会得到更多,更快的答案。 –

+2

LINQ很漂亮。可读性,更少的代码,更好的处理。 – BlueM

+0

是的,你应该更具体,什么是能力(类,...) – S3ddi9

回答

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(); 
} 
+0

+1,尽管这里假设各个类实现'IEnumerable ' –

+1

当然其他的,linq can这里不使用 – S3ddi9

+0

不一定 - 枚举可以是Class1,Class2等的属性 –

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); 
} 
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); 
+0

谢谢。我不知道SelectMany。我喜欢。 – Nick

3

假设您的播放器类是由一个PlayerClass类表示,与IDictionary<string, int>类型的Abilities属性:

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; 

但它会更好地界定与NameLevel性质的Ability类;那么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;