2012-09-07 39 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;