使用数值对 class 字符串字段 属性 进行排序
Sorting a class string field property with numerical value
我有一个 class 和一个 属性 "Name" 包含像 "1_[AnnualRevenue]","2_[ResellerType]","3_xxx"....
这样的名字
我的class就像
class xxx
{
private string fileName;
public string FileName
{
get { return fileName; }
set { fileName = value; }
}
}
我正在将值分配给 class 的对象。喜欢 xxx.FileName="1_[AnnualRevenue]";
现在我有一个列表 class。现在根据 class 属性.
对列表进行排序
现在我想按照数字顺序对字段进行排序,我的意思是1前2秒等等。
然后写入文件流
任何人都可以帮助我解决这个问题。
提前致谢。
您可以使用 LINQ 为您做到这一点
List<xxx> orderedList = unOrderedList.OrderBy(o => Convert.ToInt32(o.FileName.Split('_').First())).ToList();
代表评论编辑了答案 - 指出我们确实需要转换为整数才能正确排序。
您可以按照以下方式对列表进行排序:
List<xxx> list = new List<xxx>
{
new xxx { FileName = "3_a" },
new xxx { FileName = "1_a" },
new xxx { FileName = "2_a" },
new xxx { FileName = "8_a" }
};
var sorted = list.OrderBy(it => Convert.ToInt32(it.FileName.Split('_')[0]));//using System.Linq;
您可以将列表写入磁盘文件,如下所示:
using (TextWriter tw = new StreamWriter("C:\FileNames.txt"))
{
foreach (var item in sorted)
{
tw.WriteLine(item.FileName.ToString());
}
}
因为 属性 是一个 String
但你想按数字对它进行排序,最好的方法可能是在你的 class 上实现 IComparable
然后把CompareTo
方法中的自定义排序代码。这样你就不用每次想对一个列表进行排序时都写一个更复杂的Lambda语句,只需要对列表调用Sort()
方法即可。
您还可以处理 FileName
属性 不包含下划线或 null
的情况,而不是在 OrderBy
代码中获取异常(这是大多数其他答案会发生什么)。
我还做了一些其他更改 - 重写 ToString
方法,以便您可以轻松地将值显示到控制台 window,并使用自动 属性 语法 FileName
属性 所以我们可以删除支持字段:
class xxx : IComparable<xxx>
{
public string FileName { get; set; }
public int CompareTo(xxx other)
{
// Short circuit if any object is null, if the
// Filenames equal each other, or they're empty
if (other == null) return 1;
if (FileName == null) return (other.FileName == null) ? 0 : -1;
if (other.FileName == null) return 1;
if (FileName.Equals(other.FileName)) return 0;
if (string.IsNullOrWhiteSpace(FileName))
return (string.IsNullOrWhiteSpace(other.FileName)) ? 0 : -1;
if (string.IsNullOrWhiteSpace(other.FileName)) return 1;
// Next, try to get the numeric portion of the string to compare
int thisIndex;
int otherIndex;
var thisSuccess = int.TryParse(FileName.Split('_')[0], out thisIndex);
var otherSuccess = int.TryParse(other.FileName.Split('_')[0], out otherIndex);
// If we couldn't get the numeric portion of the string, use int.MaxValue
if (!thisSuccess)
{
// If neither has a numeric portion, just use default string comparison
if (!otherSuccess) return FileName.CompareTo(other.FileName);
thisIndex = int.MaxValue;
}
if (!otherSuccess) otherIndex = int.MaxValue;
// Return the comparison of the numeric portion of the two filenames
return thisIndex.CompareTo(otherIndex);
}
public override string ToString()
{
return FileName;
}
}
现在,您只需拨打列表中的 Sort
:
List<xxx> list = new List<xxx>
{
new xxx {FileName = "13_a"},
new xxx {FileName = "8_a"},
new xxx {FileName = null},
new xxx {FileName = "1_a"},
new xxx {FileName = "zinvalid"},
new xxx {FileName = "2_a"},
new xxx {FileName = ""},
new xxx {FileName = "invalid"}
};
list.Sort();
Console.WriteLine(string.Join("\n", list));
// Output (note the first two are the empty string and the null value):
//
//
// 1_a
// 2_a
// 8_a
// 13_a
// invalid
// zinvalid
我有一个 class 和一个 属性 "Name" 包含像 "1_[AnnualRevenue]","2_[ResellerType]","3_xxx"....
我的class就像
class xxx
{
private string fileName;
public string FileName
{
get { return fileName; }
set { fileName = value; }
}
}
我正在将值分配给 class 的对象。喜欢 xxx.FileName="1_[AnnualRevenue]";
现在我有一个列表 class。现在根据 class 属性.
对列表进行排序现在我想按照数字顺序对字段进行排序,我的意思是1前2秒等等。
然后写入文件流
任何人都可以帮助我解决这个问题。 提前致谢。
您可以使用 LINQ 为您做到这一点
List<xxx> orderedList = unOrderedList.OrderBy(o => Convert.ToInt32(o.FileName.Split('_').First())).ToList();
代表评论编辑了答案 - 指出我们确实需要转换为整数才能正确排序。
您可以按照以下方式对列表进行排序:
List<xxx> list = new List<xxx>
{
new xxx { FileName = "3_a" },
new xxx { FileName = "1_a" },
new xxx { FileName = "2_a" },
new xxx { FileName = "8_a" }
};
var sorted = list.OrderBy(it => Convert.ToInt32(it.FileName.Split('_')[0]));//using System.Linq;
您可以将列表写入磁盘文件,如下所示:
using (TextWriter tw = new StreamWriter("C:\FileNames.txt"))
{
foreach (var item in sorted)
{
tw.WriteLine(item.FileName.ToString());
}
}
因为 属性 是一个 String
但你想按数字对它进行排序,最好的方法可能是在你的 class 上实现 IComparable
然后把CompareTo
方法中的自定义排序代码。这样你就不用每次想对一个列表进行排序时都写一个更复杂的Lambda语句,只需要对列表调用Sort()
方法即可。
您还可以处理 FileName
属性 不包含下划线或 null
的情况,而不是在 OrderBy
代码中获取异常(这是大多数其他答案会发生什么)。
我还做了一些其他更改 - 重写 ToString
方法,以便您可以轻松地将值显示到控制台 window,并使用自动 属性 语法 FileName
属性 所以我们可以删除支持字段:
class xxx : IComparable<xxx>
{
public string FileName { get; set; }
public int CompareTo(xxx other)
{
// Short circuit if any object is null, if the
// Filenames equal each other, or they're empty
if (other == null) return 1;
if (FileName == null) return (other.FileName == null) ? 0 : -1;
if (other.FileName == null) return 1;
if (FileName.Equals(other.FileName)) return 0;
if (string.IsNullOrWhiteSpace(FileName))
return (string.IsNullOrWhiteSpace(other.FileName)) ? 0 : -1;
if (string.IsNullOrWhiteSpace(other.FileName)) return 1;
// Next, try to get the numeric portion of the string to compare
int thisIndex;
int otherIndex;
var thisSuccess = int.TryParse(FileName.Split('_')[0], out thisIndex);
var otherSuccess = int.TryParse(other.FileName.Split('_')[0], out otherIndex);
// If we couldn't get the numeric portion of the string, use int.MaxValue
if (!thisSuccess)
{
// If neither has a numeric portion, just use default string comparison
if (!otherSuccess) return FileName.CompareTo(other.FileName);
thisIndex = int.MaxValue;
}
if (!otherSuccess) otherIndex = int.MaxValue;
// Return the comparison of the numeric portion of the two filenames
return thisIndex.CompareTo(otherIndex);
}
public override string ToString()
{
return FileName;
}
}
现在,您只需拨打列表中的 Sort
:
List<xxx> list = new List<xxx>
{
new xxx {FileName = "13_a"},
new xxx {FileName = "8_a"},
new xxx {FileName = null},
new xxx {FileName = "1_a"},
new xxx {FileName = "zinvalid"},
new xxx {FileName = "2_a"},
new xxx {FileName = ""},
new xxx {FileName = "invalid"}
};
list.Sort();
Console.WriteLine(string.Join("\n", list));
// Output (note the first two are the empty string and the null value):
//
//
// 1_a
// 2_a
// 8_a
// 13_a
// invalid
// zinvalid