using Array.sort too sort a string

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:

enter image description here

Upvotes: 1

Views: 92

Answers (3)

@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

Tim Schmelter
Tim Schmelter

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

uTeisT
uTeisT

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 tidtilbages have a TotalSeconds property that you can easily OrderBy().

Just to give you an idea..

Upvotes: 0

Related Questions