使用 Array.sort 对字符串进行排序
using Array.sort too sort a string
所以我正在尝试制作一个 "program" 给我一个密码输出,这些密码在我的公司 AD 中很快就会过期。但我 运行 遇到了一个小问题。当我调用 "array.sort(array)" 时,因为它是一个包含时间跨度和身份名称的字符串,所以它似乎根据还剩多长时间对人们进行分组,而不是首先给出最小的数字。任何人都知道如何解决这个问题,因为它是一个字符串?
*我知道我是一个业余程序员,代码很糟糕,很难阅读!
foreach (Principal p in grp.GetMembers(false))
{
TimeSpan tidtilbage = timeToExpire.GetTimeRemainingUntilPasswordExpiration(DOMAIN, p.SamAccountName);
TimeSpan under14 = new TimeSpan(14, 00, 00, 00);
TimeSpan ikkeMinus10 = new TimeSpan(-10, 00, 00, 00);
if (tidtilbage < under14 && tidtilbage > ikkeMinus10)
{
string lines = tidtilbage.ToString("%d") + " dag(e)" + " " + tidtilbage.ToString("%h") + " time(r)" + " - " + p.SamAccountName.ToUpper() + " - " + p.DisplayName + "\n\n";
sorted[i] = lines;
Array.Sort(sorted);
i++;
}
else
continue;
}
foreach (var item in sorted)
{
if (item == null || item == "")
continue;
else
{
Console.WriteLine("{0}", item);
myWriter.WriteLine("{0}", item);
}
}
myWriter.Close();
这是我得到的输出:
所以您想按数字值在前的顺序对字符串进行排序?然后,您需要使用 int.Parse
将该子字符串转换为 int
。您可以使用 LINQ 的 OrderBy
:
进行排序
sorted = sorted
.OrderBy(s => int.Parse(new String(s.TakeWhile(Char.IsDigit).ToArray())))
.ToArray();
请注意,如果字符串不是以整数开头,这将导致异常。
但在这种情况下,最好也存储原始 TimeSpan
,这样更容易排序。
TimeSpan under14 = new TimeSpan(14, 00, 00, 00);
TimeSpan ikkeMinus10 = new TimeSpan(-10, 00, 00, 00);
sorted = grp.GetMembers(false)
.Select(account => new
{
tidtilbage = timeToExpire.GetTimeRemainingUntilPasswordExpiration(DOMAIN, account.SamAccountName),
account
})
.Select(x => new
{
x.tidtilbage,
lines = x.tidtilbage.ToString("%d") + " dag(e)" + " " + x.tidtilbage.ToString("%h") + " time(r)" + " - " + x.account.SamAccountName.ToUpper() + " - " + x.account.DisplayName + "\n\n"
})
.Where(x => x.tidtilbage < under14 && x.tidtilbage > ikkeMinus10)
.OrderBy(x => x.tidtilbage)
.Select(x => x.lines)
.ToArray()
有点偏离 OP 但因为 tidtilbage
已经是 TimeSpan
类型。您还可以使用 List
而不是 Array
并执行更清晰的操作。
示例:
List<TimeSpan> tsList = new List<TimeSpan>();
for (int i = 1; i <= 10; i++)
{
Random rnd = new Random(i);
TimeSpan ts = new TimeSpan(0,0,rnd.Next(10000));
tsList.Add(ts);
}
//This is the line you will need
tsList = tsList.OrderBy(x => x.TotalSeconds).ToList();
您的所有 tidtilbage
都有一个 TotalSeconds
属性,您可以轻松 OrderBy()
。
只是给你一个想法..
@TimSchmelter
foreach (Principal p in grp.GetMembers(false))
{
TimeSpan tidtilbage = timeToExpire.GetTimeRemainingUntilPasswordExpiration("cv.local", p.SamAccountName);
TimeSpan under14 = new TimeSpan(14, 00, 00, 00);
TimeSpan ikkeMinus10 = new TimeSpan(-10, 00, 00, 00);
sorted = grp.GetMembers(false)
.Select(x => new
{
tidtilbage = timeToExpire.GetTimeRemainingUntilPasswordExpiration("cv.local", p.SamAccountName),
lines = tidtilbage.ToString("%d") + " dag(e)" + " " + tidtilbage.ToString("%h") + " time(r)" + " - " + p.SamAccountName.ToUpper() + " - " + p.DisplayName + "\n\n"
})
.Where(x => x.tidtilbage < under14 && x.tidtilbage > ikkeMinus10)
.OrderBy(x => x.tidtilbage)
.Select(x => x.lines)
.ToArray();
i++;
}
所以我正在尝试制作一个 "program" 给我一个密码输出,这些密码在我的公司 AD 中很快就会过期。但我 运行 遇到了一个小问题。当我调用 "array.sort(array)" 时,因为它是一个包含时间跨度和身份名称的字符串,所以它似乎根据还剩多长时间对人们进行分组,而不是首先给出最小的数字。任何人都知道如何解决这个问题,因为它是一个字符串? *我知道我是一个业余程序员,代码很糟糕,很难阅读!
foreach (Principal p in grp.GetMembers(false))
{
TimeSpan tidtilbage = timeToExpire.GetTimeRemainingUntilPasswordExpiration(DOMAIN, p.SamAccountName);
TimeSpan under14 = new TimeSpan(14, 00, 00, 00);
TimeSpan ikkeMinus10 = new TimeSpan(-10, 00, 00, 00);
if (tidtilbage < under14 && tidtilbage > ikkeMinus10)
{
string lines = tidtilbage.ToString("%d") + " dag(e)" + " " + tidtilbage.ToString("%h") + " time(r)" + " - " + p.SamAccountName.ToUpper() + " - " + p.DisplayName + "\n\n";
sorted[i] = lines;
Array.Sort(sorted);
i++;
}
else
continue;
}
foreach (var item in sorted)
{
if (item == null || item == "")
continue;
else
{
Console.WriteLine("{0}", item);
myWriter.WriteLine("{0}", item);
}
}
myWriter.Close();
这是我得到的输出:
所以您想按数字值在前的顺序对字符串进行排序?然后,您需要使用 int.Parse
将该子字符串转换为 int
。您可以使用 LINQ 的 OrderBy
:
sorted = sorted
.OrderBy(s => int.Parse(new String(s.TakeWhile(Char.IsDigit).ToArray())))
.ToArray();
请注意,如果字符串不是以整数开头,这将导致异常。
但在这种情况下,最好也存储原始 TimeSpan
,这样更容易排序。
TimeSpan under14 = new TimeSpan(14, 00, 00, 00);
TimeSpan ikkeMinus10 = new TimeSpan(-10, 00, 00, 00);
sorted = grp.GetMembers(false)
.Select(account => new
{
tidtilbage = timeToExpire.GetTimeRemainingUntilPasswordExpiration(DOMAIN, account.SamAccountName),
account
})
.Select(x => new
{
x.tidtilbage,
lines = x.tidtilbage.ToString("%d") + " dag(e)" + " " + x.tidtilbage.ToString("%h") + " time(r)" + " - " + x.account.SamAccountName.ToUpper() + " - " + x.account.DisplayName + "\n\n"
})
.Where(x => x.tidtilbage < under14 && x.tidtilbage > ikkeMinus10)
.OrderBy(x => x.tidtilbage)
.Select(x => x.lines)
.ToArray()
有点偏离 OP 但因为 tidtilbage
已经是 TimeSpan
类型。您还可以使用 List
而不是 Array
并执行更清晰的操作。
示例:
List<TimeSpan> tsList = new List<TimeSpan>();
for (int i = 1; i <= 10; i++)
{
Random rnd = new Random(i);
TimeSpan ts = new TimeSpan(0,0,rnd.Next(10000));
tsList.Add(ts);
}
//This is the line you will need
tsList = tsList.OrderBy(x => x.TotalSeconds).ToList();
您的所有 tidtilbage
都有一个 TotalSeconds
属性,您可以轻松 OrderBy()
。
只是给你一个想法..
@TimSchmelter
foreach (Principal p in grp.GetMembers(false))
{
TimeSpan tidtilbage = timeToExpire.GetTimeRemainingUntilPasswordExpiration("cv.local", p.SamAccountName);
TimeSpan under14 = new TimeSpan(14, 00, 00, 00);
TimeSpan ikkeMinus10 = new TimeSpan(-10, 00, 00, 00);
sorted = grp.GetMembers(false)
.Select(x => new
{
tidtilbage = timeToExpire.GetTimeRemainingUntilPasswordExpiration("cv.local", p.SamAccountName),
lines = tidtilbage.ToString("%d") + " dag(e)" + " " + tidtilbage.ToString("%h") + " time(r)" + " - " + p.SamAccountName.ToUpper() + " - " + p.DisplayName + "\n\n"
})
.Where(x => x.tidtilbage < under14 && x.tidtilbage > ikkeMinus10)
.OrderBy(x => x.tidtilbage)
.Select(x => x.lines)
.ToArray();
i++;
}