Reputation: 803
so iam trying to make a "program" that gives me a output of passwords that is soon to expire in my companies AD. but ive run into a petit problem. when i call "array.sort(array)" then because its a string containing a timespan and names of who it is, it seems like it groups people on how long there is left, but not making the smallest number first. anyone have an idea on how to fix this as it is a string? *I know iam a amateur programmer with lousy code, that hard to read!
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();
this is the output i get:
Upvotes: 1
Views: 92
Reputation: 803
@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++;
}
Upvotes: 0
Reputation: 460058
So you want to sort the strings by the numeric value that comes first? Then you need to convert that substring to int
with int.Parse
. You can order with LINQ's OrderBy
:
sorted = sorted
.OrderBy(s => int.Parse(new String(s.TakeWhile(Char.IsDigit).ToArray())))
.ToArray();
Note that this will cause an exception if the string doesn't start with an integer.
But in this case it might be better to store the original TimeSpan
also, then it's easiert to sort.
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()
Upvotes: 2
Reputation: 2266
A little bit off of OP but as tidtilbage
is already TimeSpan
type. You could also use a List
, instead of an Array
and perform clearer looking operations.
A sample example:
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();
All your tidtilbage
s have a TotalSeconds
property that you can easily OrderBy()
.
Just to give you an idea..
Upvotes: 0