如何对包含双精度和字符串数据的 Class 列表进行排序
How to Sort a Class List that contain both of double and string data
人class:
class Person
{
public string ID;
public string Name;
public string PClass;
public string Age;
public string Sex;
public string Survived;
public string SexCode;
public Person(string id,string name,string pclass,string age,string sex,
string survived,string sexcode)
{
ID = id;
Name = name;
PClass = pclass;
Age = age;
Sex = sex;
Survived = survived;
SexCode = sexcode;
}
我的程序代码:
class Program
{
static void Main(string[] args)
{
string[] data = File.ReadAllLines("titanic.csv");
data = data.Skip(1).ToArray();
List<Person> personList = new List<Person>();
List<Person> personList_name = new List<Person>();
List<Person> personList_pclass = new List<Person>();
List<Person> personList_age = new List<Person>();
List<Person> personList_sex = new List<Person>();
List<Person> personList_id = new List<Person>();
for (int i = 0; i < data.Length; i++)
{
string[] temp = Regex.Split(data[i], ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)");
Person person = new Person(temp[0], temp[1], temp[2],temp[3],
temp[4], temp[5], temp[6]);
personList.Add(person);
}
personList_name = personList.OrderBy(x => x.Name).ToList();
personList_pclass = personList.OrderBy(z => z.PClass).ToList();
personList_sex = personList.OrderBy(w => w.Sex).ToList();
int id_;
int age_;
personList_age = personList.OrderBy(y => int.TryParse(y.Age, out age_)).ToList();
//personList_id = personList.OrderByDescending(int.TryParse(ID, out number)).ToList();
personList_id = personList.OrderBy(o => int.TryParse(o.ID, out id_)).ToList();
while (true)
{
Console.WriteLine(" Please select your filtring method:\n" +
"1-By Name\n2-By Pclass\n3-By Age\n4-By Sex\n5-By ID\n Press -1 to quit.");
string selection = Console.ReadLine();
if (selection == "-1")
{
break;
}
Console.WriteLine(("{0,-10}{1,70}{2,20}{3,20}{4,20}{5,20}{6,20}"), item.ID.Trim('"'), item.Name.Trim('"'), item.PClass.Trim('"')
, item.Age, item.Sex.Trim('"'), item.Survived.Trim('"')
, item.SexCode.Trim('"'));
}
}
if (selection == "3")
{
Console.WriteLine(("{0,-10}{1,70}{2,20}{3,20}{4,20}{5,20}{6,20}"), "ID", "NAME", "PCLASS", "AGE", "SEX", "SURVIVED", "SEXCODE");
foreach (var item in personList_age)
{
Console.WriteLine(("{0,-10}{1,70}{2,20}{3,20}{4,20}{5,20}{6,20}"), item.ID.Trim('"'), item.Name.Trim('"'), item.PClass.Trim('"')
, item.Age, item.Sex.Trim('"'), item.Survived.Trim('"')
, item.SexCode.Trim('"'));
}
}
}
}
}
我可以对 CSV 文件中的字符串数据进行排序,例如姓名,但是对于年龄和 ID,我无法获得正确的顺序(升序或降序)
我已经搜索了很多关于这个问题的信息。尝试使用 Icomparable 和 Tryparse
但没有任何积极的结果。问题是 Orderby 将年龄和 ID 作为字符串处理。但是,如果我将 Age 和 ID 定义为 double 或 int,我将在定义临时数组时得到 "cannot convert"。请提供任何有用的建议或解决方案?
这就是我根据年龄订购时发生的情况。看来还是按ID点餐!
(来源:up-00.com)
提供函数而不是表达式:
personList_age = personList.OrderBy
(
y => {
int age;
bool ok = int.TryParse(y.Age, out age);
return ok ? age : default(int);
}
).ToList();
或者为了保持整洁可以写一个扩展方法:
static void int ToInt(this string input)
{
int n;
bool ok = int.TryParse(input, out n);
return ok ? n : default(int);
}
然后这样调用:
personList_age = personList.OrderBy( y => t.Age.ToInt());
你试过了吗
personList.OrderBy(x => Convert.ToInt32(x.id)).ToList();
?
这样它应该按整数值对它们进行排序
问题是 TryParse
returns 一个 bool
而不是解析值。 OrderBy
然后命令 true
vs false
。在升序中,false
在 之前 true
.
如果您希望这些值始终是整数,您有几种选择。
更好的(在我看来)是将 class 中的那些属性更改为整数并在构造函数中进行解析,如果传递了错误的值则抛出异常(不允许错误的 Person
待创建)。
第二个选项是在 OrderBy
内切换到 int.Parse
。这只有在所有值都可以被解析时才有效,否则会抛出异常。
如果你必须使用TryParse
(例如它不能保证是整数数据并且你不能改变你的class定义),你可以使用多语句lambda:
personList.OrderBy(person => {
int value;
return int.TryParse(person.ID, out value) ? value : -1;
});
您可能希望根据您希望它们排序的位置为失败案例选择不同的值。在上面的例子中,所有的失败都会首先出现——尽管 假设 没有 ID
可能是负数。您可以改用 int.MinValue
。如果你想让它们最后出现,你可以使用 int.MaxValue
——尽管如果你的 ID
s 可以合法地那么大,你就会遇到问题(我认为至少可以安全地假设没有人会有一个 age
那么大)。
另一种选择是通过首先使用 Select
创建一个包含您需要的数据的匿名类型来过滤掉失败(成功解析,如果适用,值和您的原始 Person
)。然后使用 Where
过滤我们无法解析的任何值,然后对解析的数据使用 OrderBy
。最后使用另一个 Select
从匿名类型中提取你的 Person
。
personList.Select(p => {
int value;
var ok = int.TryParse(p.ID, out value);
return new { Ok = ok, ID = value, Person = p };
})
.Where(result => result.Ok)
.OrderBy(result => result.ID)
.Select(result => result.Person);
人class:
class Person
{
public string ID;
public string Name;
public string PClass;
public string Age;
public string Sex;
public string Survived;
public string SexCode;
public Person(string id,string name,string pclass,string age,string sex,
string survived,string sexcode)
{
ID = id;
Name = name;
PClass = pclass;
Age = age;
Sex = sex;
Survived = survived;
SexCode = sexcode;
}
我的程序代码:
class Program
{
static void Main(string[] args)
{
string[] data = File.ReadAllLines("titanic.csv");
data = data.Skip(1).ToArray();
List<Person> personList = new List<Person>();
List<Person> personList_name = new List<Person>();
List<Person> personList_pclass = new List<Person>();
List<Person> personList_age = new List<Person>();
List<Person> personList_sex = new List<Person>();
List<Person> personList_id = new List<Person>();
for (int i = 0; i < data.Length; i++)
{
string[] temp = Regex.Split(data[i], ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)");
Person person = new Person(temp[0], temp[1], temp[2],temp[3],
temp[4], temp[5], temp[6]);
personList.Add(person);
}
personList_name = personList.OrderBy(x => x.Name).ToList();
personList_pclass = personList.OrderBy(z => z.PClass).ToList();
personList_sex = personList.OrderBy(w => w.Sex).ToList();
int id_;
int age_;
personList_age = personList.OrderBy(y => int.TryParse(y.Age, out age_)).ToList();
//personList_id = personList.OrderByDescending(int.TryParse(ID, out number)).ToList();
personList_id = personList.OrderBy(o => int.TryParse(o.ID, out id_)).ToList();
while (true)
{
Console.WriteLine(" Please select your filtring method:\n" +
"1-By Name\n2-By Pclass\n3-By Age\n4-By Sex\n5-By ID\n Press -1 to quit.");
string selection = Console.ReadLine();
if (selection == "-1")
{
break;
}
Console.WriteLine(("{0,-10}{1,70}{2,20}{3,20}{4,20}{5,20}{6,20}"), item.ID.Trim('"'), item.Name.Trim('"'), item.PClass.Trim('"')
, item.Age, item.Sex.Trim('"'), item.Survived.Trim('"')
, item.SexCode.Trim('"'));
}
}
if (selection == "3")
{
Console.WriteLine(("{0,-10}{1,70}{2,20}{3,20}{4,20}{5,20}{6,20}"), "ID", "NAME", "PCLASS", "AGE", "SEX", "SURVIVED", "SEXCODE");
foreach (var item in personList_age)
{
Console.WriteLine(("{0,-10}{1,70}{2,20}{3,20}{4,20}{5,20}{6,20}"), item.ID.Trim('"'), item.Name.Trim('"'), item.PClass.Trim('"')
, item.Age, item.Sex.Trim('"'), item.Survived.Trim('"')
, item.SexCode.Trim('"'));
}
}
}
}
}
我可以对 CSV 文件中的字符串数据进行排序,例如姓名,但是对于年龄和 ID,我无法获得正确的顺序(升序或降序) 我已经搜索了很多关于这个问题的信息。尝试使用 Icomparable 和 Tryparse 但没有任何积极的结果。问题是 Orderby 将年龄和 ID 作为字符串处理。但是,如果我将 Age 和 ID 定义为 double 或 int,我将在定义临时数组时得到 "cannot convert"。请提供任何有用的建议或解决方案?
这就是我根据年龄订购时发生的情况。看来还是按ID点餐!
(来源:up-00.com)
提供函数而不是表达式:
personList_age = personList.OrderBy
(
y => {
int age;
bool ok = int.TryParse(y.Age, out age);
return ok ? age : default(int);
}
).ToList();
或者为了保持整洁可以写一个扩展方法:
static void int ToInt(this string input)
{
int n;
bool ok = int.TryParse(input, out n);
return ok ? n : default(int);
}
然后这样调用:
personList_age = personList.OrderBy( y => t.Age.ToInt());
你试过了吗
personList.OrderBy(x => Convert.ToInt32(x.id)).ToList();
?
这样它应该按整数值对它们进行排序
问题是 TryParse
returns 一个 bool
而不是解析值。 OrderBy
然后命令 true
vs false
。在升序中,false
在 之前 true
.
如果您希望这些值始终是整数,您有几种选择。
更好的(在我看来)是将 class 中的那些属性更改为整数并在构造函数中进行解析,如果传递了错误的值则抛出异常(不允许错误的 Person
待创建)。
第二个选项是在 OrderBy
内切换到 int.Parse
。这只有在所有值都可以被解析时才有效,否则会抛出异常。
如果你必须使用TryParse
(例如它不能保证是整数数据并且你不能改变你的class定义),你可以使用多语句lambda:
personList.OrderBy(person => {
int value;
return int.TryParse(person.ID, out value) ? value : -1;
});
您可能希望根据您希望它们排序的位置为失败案例选择不同的值。在上面的例子中,所有的失败都会首先出现——尽管 假设 没有 ID
可能是负数。您可以改用 int.MinValue
。如果你想让它们最后出现,你可以使用 int.MaxValue
——尽管如果你的 ID
s 可以合法地那么大,你就会遇到问题(我认为至少可以安全地假设没有人会有一个 age
那么大)。
另一种选择是通过首先使用 Select
创建一个包含您需要的数据的匿名类型来过滤掉失败(成功解析,如果适用,值和您的原始 Person
)。然后使用 Where
过滤我们无法解析的任何值,然后对解析的数据使用 OrderBy
。最后使用另一个 Select
从匿名类型中提取你的 Person
。
personList.Select(p => {
int value;
var ok = int.TryParse(p.ID, out value);
return new { Ok = ok, ID = value, Person = p };
})
.Where(result => result.Ok)
.OrderBy(result => result.ID)
.Select(result => result.Person);