2017-05-24 17 views
0

私はテキストファイルに書き込まれた配列のリストを持っています。各配列には7つの項目があります。最初の項目はクラスの日付で、次の6つの項目はその日付にタスクが与えられた学生IDです。 私は、配列のリストをスキャンし、各生徒が選択された日付を別々のファイルに書きたいと思っています。配列のforeachループとifステートメントを使用して配列の最初の項目を返します

たとえば、学生04が複数選択されている場合、ファイルには、学生にタスクが与えられた日付が4行目に表示されます。 私は、各行をスキャンするために各ループにaを使用しようとしています。保存された配列のリストの

例データ:

 
00/00/0000,02,04,05,06,07,08 
11/11/1111,01,02,05,06,08,09 
22/22/2222,02,03,05,06,07,08

何私が達成したいことは、このように、studentId,taskDate(学生が複数のタスクを行っている場合には、複数)である。これまでのところ

 
01,11/11/1111 
02,00/00/0000,11/11/1111,22/22/2222 
03,22/22/2222 
04,00/00/0000 
05,00/00/0000,11/11/1111,22/22/2222 
06,00/00/0000,11/11/1111,22/22/2222 
07,00/00/0000,22/22/2222 
08,00/00/0000,11/11/1111,22/22/2222

I今私は、リストのANをスキャンしようとしています

string readrecord = @"C:\classes\tasks\taskrecord.txt"; 

List<string> lines = File.ReadAllLines(readrecord).ToList(); 

foreach (var line in lines) 
{ 
    string[] tasks= entries[1].Split(','); 
    taskDate = tasks[0]; 
    stu1 = tasks[1]; 
    stu2 = tasks[2]; 
    stu3 = tasks[3]; 
    stu4 = tasks[4]; 
    stu5 = tasks[5]; 
    stu6 = tasks[6]; 
} 

を次のようにテキストファイルから読み込みます

string writeTaskDate = @"C:\classes\tasks\dateRecord.txt"; 

if(stu1 == 01||stu2 == 01||stu3 == 01||stu4 == 01||stu5 == 01||stu6 == 01) 
{ 
//--How do i add taskDate to end of Line 1 of "writeTaskDate"?? 
} 

else If(stu1 == 02||stu2 == 02||stu3 == 02||stu4 == 02||stu5 == 02||stu6 == 02 
{ 
//--How do i add taskDate to end of Line 2 of "writeTaskDate"?? 
} 

...というように、各学生のために私はIDを持っている:stu1stu6には、特定の生徒のIDと等しい場合はファイルにtaskDateを書くdは。アドバイスをいただければ幸いです。

+0

申し訳ありませんが、例のフォーマットはうまくいかなかった – Daithi

+0

あなたの投稿を変更するには[編集]ボタン(https://stackoverflow.com/posts/44169497/edit)を使用することができます –

答えて

1

これは動作するはずです:

//Prep work/data structures 
var students = new SortedDictionary<string, List<string>>(); 
Action<string, string> AddStudentTask = (student, taskDate) => { 
    if (!students.ContainsKey(student)) 
     students.Add(student, new List<string>()); 

    students[student].Add(taskDate); 
}; 

//Read existing data 
string readrecord = @"C:\classes\tasks\taskrecord.txt"; 
var lines = File.ReadLines(readrecord).Select(l => l.Split(',')); 
foreach (var line in lines) 
{ 
    AddStudentTask(line[1], line[0]); 
    AddStudentTask(line[2], line[0]); 
    AddStudentTask(line[3], line[0]); 
    AddStudentTask(line[4], line[0]); 
    AddStudentTask(line[5], line[0]); 
    AddStudentTask(line[6], line[0]); 
} 

//Write new data 
string writeTaskDate = @"C:\classes\tasks\dateRecord.txt"; 
using (var sw = new StreamWriter(writeTaskDate)) 
{ 
    foreach (var item in students) 
    { 
     sw.Write(item.Key); 
     sw.Write(","); 
     sw.WriteLine(String.Join(",", item.Value)); 
    } 
} 

しかし、それは、辞書に基づいています。あなたの学生IDのすべてが数値で連続的でギャップが少ないことが分かっていて、その数がわかっている場合は、ディクショナリの代わりにListまたはArrayを使用すると、ListインデックスがStudent IDに対応します/辞書のキーフィールド。

+0

これは私が提案するつもりだったが、ほんのちょっと書かれた。 (私はラムダの考えが好きです、決してそれについて自分自身について考えたことはありません:-))+1 –

+0

正直言って、私は通常、ラムダを同じクラスのプライベートな名前付きメソッドにするでしょう。しかし、私は質問からクラスのコンテキストを持っていないので、これは "コピー/貼り付けから私の既存のメソッド"の観点から優れています。また、IIRC、C#7はこれに対してより洗練された構文を持っています。 –

0

いくつかの拡張メソッドを使用して:あなたはそうのようなLINQを乱用することができます

public static TRes CDR<T, TRes>(this IEnumerable<T> lines, Func<T, IEnumerable<T>, TRes> resultFunc) => resultFunc(lines.First(), lines.Skip(1)); 
public static string Join(this IEnumerable<string> strings, char sep) => String.Join(sep.ToString(), strings.ToArray()); 
public static IEnumerable<T> Prepend<T>(this IEnumerable<T> rest, params T[] first) => first.Concat(rest); 

を:

var ans = lines.SelectMany(s => s.Split(',').CDR((d, sids) => sids.Select(sid => new { date = d, id = sid }))).OrderBy(did => did.id) 
      .GroupBy(did => did.id, (id, didg) => didg.Select(did => did.date).Prepend(id).Join(',')); 

または拡張子なし:

var ans = lines.SelectMany(s => { var ls = s.Split(','); return ls.Skip(1).Select(sid => new { date = ls[0], id = sid }); }).OrderBy(did => did.id) 
      .GroupBy(did => did.id, (id, didg) => id+","+String.Join(",", didg.Select(did => did.date))).Dump(); 

しかし、私はそれをお勧めしません。あなたが好きしかし

var res = new Dictionary<string, List<string>>(); 
foreach (var s in lines) { 
    var ls = s.Split(','); 
    var d = ls[0]; 
    foreach (var id in ls.Skip(1)) { 
     if (res.ContainsKey(id)) 
      res[id].Add(d); 
     else 
      res[id] = new List<string> { d }; 
    } 
} 
var ans = new List<string>(); 
foreach (var id in res.Keys.OrderBy(k => k)) { 
    ans.Add(id+","+String.Join(",", res[id])); 
} 

は、それからちょうど出力ans:代わりにこれを行います。 ansに追加するのではなく、最後の方法で作成したときに各行を出力することもできます。

+2

私はあなたが実際にこれらのような変数名を実際に使用しないことを願っています。それ以外の場合は、あなたのコードが何をしているのかを理解する必要があるときには、今から6ヵ月後に自分自身を憎むでしょう –

+0

私は彼らが何年も理解できると思っています。 'd'は日付です。 'sid'はStudentIDです。 'sids'はStudentIDSです。 'did'はDate + IDです。 'didg'は、Date + ID Groupです。 – NetMage

+0

個人的には、新聞は一度も好きではありませんでした。あなたのコードをメンテナンスしようとしている悪質な人が他の誰かであればどうでしょうか?彼または彼女はこのコードを理解する価値がありませんか? –

関連する問題