我想首先按年龄排序此列表中的名称(我到目前为止已经完成),但我想知道如何在打印到新文件之前再按姓氏对这些名称进行排序。例如,如果我有5个年龄在20岁且姓名不同的人,我怎样才能确保这5个人按字母顺序递增?
setDT(df1)[, ret := round((Price/shift(Price))-1, 2), by = SecTicker][]
答案 0 :(得分:4)
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;
}
似乎可以为我的快速测试工作,但测试更多:)。
答案 1 :(得分:1)
您可以使用Linq:
people.OrderBy(person => person.age)
.ThenBy(person => person.LastName);
答案 2 :(得分: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());
答案 3 :(得分: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);
}
}
答案 4 :(得分: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}";
}