2016-11-15 21 views
0

このリストの名前を最初に年齢別にソートしたいのですが(今まで私が行ったことですが)、新しいファイルに印刷する前の姓。たとえば、姓が異なる20歳の5人の人がいる場合、その5人がアルファベット順に昇順になっていることを確認するにはどうすればよいですか?名前のリストを姓と年号で並べ替えるC#

class Person : IComparable 
{ 
    string vorname; 
    string nachname; 
    int age; 

    public Person(string vorname, string nachname, int age) 
    { 
     this.age = age; 
     this.nachname = nachname; 
     this.vorname = vorname; 
    } 

    public int CompareTo(object obj) 
    { 
     Person other = (Person)obj; 
     int a = this.age - other.age; 

     if (a != 0) 
     { 
      return -a; 
     } 
     else 
     { 
      return age.CompareTo(other.age); 
     } 
    } 

    public override string ToString() 
    { 
     return vorname + " " + nachname + "\t" + age; 
    }   
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Person[] peeps = new Person[20]; 

     try 
     { 
      StreamReader sr = new StreamReader("inputNames.txt"); 

      int count = 0; 

      while (!sr.EndOfStream) 
      { 
       string data = sr.ReadLine(); 
       Console.WriteLine(); 
       string[] info = data.Split(','); 
       peeps[count] = new Person(info[0], info[1], int.Parse(info[2])); 

       count++; 
      } 
      Array.Sort(peeps); 
      sr.Close(); 
     } 
     catch(FileNotFoundException e) 
     { 
      Console.WriteLine(e.Message); 
     } 

     StreamWriter sw = new StreamWriter("outputNames.txt"); 

     Console.WriteLine(); 
     foreach (Person p in peeps) 
     { 
      Console.WriteLine(p); 
      sw.WriteLine(p); 
     } 
     sw.Close(); 
    } 
} 
+0

EDIT * linqなしでは、IComparableを使用する必要があります。 –

答えて

3

Linqはあなたの友人です。あなたは1行にすべてのコードを書き直すことができます:

peeps.OrderBy(x => x.Age).ThenBy(x => x.LastName); 

それがすべてです。あなたは、IComparableジャンク、古い学校のすべてを取り除くことができます。

EDIT:IComparableをのために、あなたが行うことができます:

public int CompareTo(object obj) 
    { 
     Person other = (Person)obj; 

     if (age < other.age) 
      return -1; 

     if (String.Compare(vorname, other.vorname) < 0) 
      return -1; 

     return 1; 
    } 

私の迅速なテストのために動作しますが、より多くのそれをテストするようだ:)。

+0

私は学校でこれをやっていると言いましたが、私はIComparableを使わなければならないと言いました。申し訳ありません –

+0

@ JustinL、IComparableを使用する私の答えを更新しました。 – SledgeHammer

+0

それは名前のために働く、しかし年齢番号は順序不順です。 :/ –

1

あなたはLINQを使用することができます:

people.OrderBy(person => person.age) 
    .ThenBy(person => person.LastName); 
1

リトルビット昔ながらの、まだ。あなたはComparersを使用し、柔軟性を望むように、後でそれらを使用することができます。

public class AgeComparer: Comparer<Person> 
    { 
     public override int Compare(Person x, Person y) 
     { 

      return x.Age.CompareTo(y.Age);  
     }  
    } 
    public class LastNameThenAgeComparer: Comparer<Person> 
    { 
     public override int Compare(Person x, Person y) 
     {  
      if (x.LastName.CompareTo(y.LastName) != 0) 
      { 
       return x.LastName.CompareTo(y.LastName); 
      } 
      else (x.Age.CompareTo(y.Age) != 0) 
      { 
       return x.Age.CompareTo(y.Age); 
      }  
     }  
    } 
//// other types of comparers 

使用法:

personList.Sort(new LastNameThenAgeComparer()); 
0

LINQ +拡張メソッド

class Program 
{ 
    static void Main(string[] args) 
    { 
     try 
     { 
      "inputNames.txt".ReadFileAsLines() 
          .Select(l => l.Split(',')) 
          .Select(l => new Person 
          { 
           vorname = l[0], 
           nachname = l[1], 
           age = int.Parse(l[2]), 
          }) 
          .OrderBy(p => p.age).ThenBy(p => p.nachname) 
          .WriteAsLinesTo("outputNames.txt"); 
     } 
     catch (Exception e) 
     { 
      Console.Error.WriteLine(e.Message); 
     } 
    } 
} 
public class Person 
{ 
    public string vorname { get; set; } 
    public string nachname { get; set; } 
    public int age { get; set; } 

    public override string ToString() 
    { 
     return string.Format("{0} {1}\t{2}", this.vorname, this.nachname, this.age); 
    } 
} 
public static class ToolsEx 
{ 
    public static IEnumerable<string> ReadFileAsLines(this string filename) 
    { 
     using (var reader = new StreamReader(filename)) 
      while (!reader.EndOfStream) 
       yield return reader.ReadLine(); 
    } 
    public static void WriteAsLinesTo(this IEnumerable lines, string filename) 
    { 
     using (var writer = new StreamWriter(filename)) 
      foreach (var line in lines) 
       writer.WriteLine(line); 
    } 
} 
0

これは私がそのような人を実装する方法をありますいくつかのコメントとクラス。

//sort a person object by age first, then by last name 
    class Person : IComparable<Person>, IComparable 
    { 
     public string LastName { get; } 
     public string FirstName { get; } 
     public int Age { get; } 

     public Person(string vorname, string nachname, int age) 
     { 
      LastName = vorname; 
      FirstName = nachname; 
      Age = age; 
     } 

     // used by the default comparer 
     public int CompareTo(Person p) 
     { 
      // make sure comparable being consistent with equality; this will use IEquatable<Person> if implemented on Person hence better than static Equals from object 
      if (EqualityComparer<Person>.Default.Equals(this, p)) return 0; 

      if (p == null) 
       throw new ArgumentNullException(nameof(p), "Cannot compare person with null"); 

      if (Age.CompareTo(p.Age) == 0) 
      { 
       return LastName.CompareTo(p.LastName); 
      } 
      return Age.CompareTo(p.Age); 
     } 

     // explicit implementation for backward compatiability 
     int IComparable.CompareTo(object obj) 
     { 
      Person p = obj as Person; 
      return CompareTo(p); 
     } 

     public override string ToString() => $"{LastName} {FirstName} \t {Age}"; 
    } 
関連する問題