2016-11-15 390 views
0

我想根據年齡排序列表中的姓名(迄今爲止我已經完成),但是我想知道如何才能再按這些姓名排序打印到新文件之前的姓氏。例如,如果我有5個20歲不同姓氏的人,我怎麼能確保這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

編輯*沒有LINQ,我必須使用IComparable。 –

回答

3

Linq是你的朋友。你可以重寫所有的代碼在1行:

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

這就是它的一切:)。你可以擺脫所有那些IComparable垃圾,這是舊學校。

編輯:爲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}"; 
    } 
相關問題