2017-06-10 3 views
0

は私がDictionary<int, List<string>>enrolledStudents文字列sがリスト内にあるかどうかをチェックする方法ディクショナリ<int、List <string>>のC#で?

keyが紙コードであるint型、である持っています。 valueは、私が知りたいのです何の文字列は、学生の名前

ある文字列のリストであり、どのように私はstring sは、たとえば

については enrolledStudents

の内側に、このリスト内にあるかどうかを確認するんですこの検索は直線的であることをLINQ

return enrolledStudents.FirstOrDefault(kvp => kvp.Value.Contains(s)).Key; 

ノートを使用して

if(string s in List<string> of enrolledStudents){ 
    return enrolledStudent.key; 
} 
+0

は、キーが生徒の名前と紙のコードがある辞書を使用してみてください値。次に、単純にif(enrolledStudents.ContainsKey(studentName))がenrolledStudents [studentName]を返します。 – burkay

+0

しかし、1人の学生に複数の紙がある場合はどうしますか?彼らは複数の論文に登録するからです。 – Donald

+0

良い点ですから、n対nの関係について言及します。デザインの意思決定が必要なように見えます。あなたの質問のほとんどが「特定の論文に登録した人」であれば、それをあなたの方法で保ち、@ M.kazem Akhgaryの答えを下記のように使用します。そして、あなたの質問のほとんどが「特定の学生が登録した論文」でしょう。値のタイプをList に変更した後で両方のタイプの問合せを頻繁に行う場合は、2つのディクショナリを宣言して両方を同時に使用できますが、データの一貫性には注意してください。 – burkay

答えて

0

ソリューション

Dictionary<int, List<string>> group = new Dictionary<int, List<string>>(); 
List<string> newList = new List<string> { "Orange", "Strawberry", "Banana"}; 
group.Add(1, newList); //Group of Fruits 

newList = new List<string> { "Hulk", "Spiderman", "Batman" }; 
group.Add(2, newList); //Group of Super-Heroes 

int GroupKey = 0; 
foreach(var groupItem in group) 
{ 
    foreach(var stringValue in groupItem.Value) 
    { 
     if(stringValue == "Spiderman") 
     { 
      GroupKey = groupItem.Key; 
      break; 
     } 
    } 
    if(GroupKey > 0) 
     break 
} 

//あなたのケースで使用する必要があると思われる2番目の解決方法 (すべての学生には1つのキー(数値)しかないので、おそらくあなたが作業している場合のみ、文字列とリストを使用する方が良いでしょうあなたが学生の名前で辞書を照会し、紙のコードを取得したい場合は、1番目のソリューションを検討すべきである学生のグループ)

Dictionary<int, string> enrolledStudents = new Dictionary<int, string>(); 
enrolledStudents.Add(1, "Jamie Fox"); //Student 1 
enrolledStudents.Add(2, "Arnold Spenser"); //Student 2 
enrolledStudents.Add(3, "Jack & Jones"); //Student 3 

int StudentNumber = 0; 
foreach (var student in enrolledStudents) 
{ 
    if(student.Value == "Arnold Spenser") 
    { 
     StudentNumber = student.Key; 
     break; 
    } 
} 
0

。 コメントに記載されているように、検索速度を最適化するためにもう一度別の辞書を作成することができます。

Dictionary<string, List<int>> pageMap = enrolledStudents 
        .SelectMany(kvp => 
         kvp.Value.Select(value => new { Key = value, Value = kvp.Key })) 
        .GroupBy(a => a.Key) 
        .ToDictionary(a => a.Key, a => a.Select(x => x.Value).ToList()); 

ここで、ページマップを使用して、このような生徒のページを取得できます。

return pageMap[s]; 
+0

私は誤読している可能性がありますが、リストを平坦化しても同じキーを使用しようとした場合、重複キーに問題はありませんか? – Chris

+0

最初の部分は線形ではないようです。 n個のクラスとm個の生徒が存在する場合、最悪の場合、存在しない生徒の名前を問い合せるなど、複雑さはO(nm)になります。 – burkay

+0

リニアスチルです。それは指数関数的ではない。 @burkay –

0
Dictionary<int, List<string>> enrolledStudents = new Dictionary<int, List<string>>(); 
bool any = enrolledStudents.Any(x => x.Value.Contains("myString")); 

場合やFirstOrDefault()あなたが最初のキー

var key = enrolledStudents.FirstOrDefault(kvp => kvp.Value.Contains(s))?.Key ?? ""; 

をしたい場合は、単一の疑問符を注意ヌルを返します。

1

特定の学生のためのすべての用紙コードを取得するには、あなただけ行うことができます。

List<int> paperCodesForStudent = enrolledStudents 
    .Where(item => item.Value.Contains("studentName")) 
    .Select(item => item.Key) 
    .ToList(); 

あなたがこの方法で作ることができる、そしてあなたは、名前の確認のための大文字と小文字を区別しない比較を追加することができます。

LINQ

// 1-STのソリューションなし

private static List<int> GetPaperCodesForStudent(string studentName, 
    Dictionary<int, List<string>> enrolledStudents) 
{ 
    return enrolledStudents 
     .Where(item => item.Value.Any(name => 
      name.Equals(studentName, StringComparison.OrdinalIgnoreCase))) 
     .Select(item => item.Key) 
     .ToList(); 
} 
関連する問題