2016-11-15 9 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

linq 없이는 IComparable을 사용해야합니다. –

답변

3

Linq는 친구입니다. 모든 코드를 한 줄에 다시 쓸 수 있습니다 :

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}"; 
    }