1

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

5
  • So whats the problem ?! Commented Aug 26, 2016 at 11:21
  • I think his problem is, that he wants to sort by days instead of sort by string of timespan. "11" as string comes before "4" as string. Commented Aug 26, 2016 at 11:23
  • indeed Sebastian :) Commented Aug 26, 2016 at 11:45
  • "petit problem" your french is coming out man XD Commented Aug 26, 2016 at 11:52
  • Nah man, its international(ish) :-D, you knew what i meant! Commented Aug 26, 2016 at 12:00

3 Answers 3

2

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()
Sign up to request clarification or add additional context in comments.

6 Comments

Must also parse the next int (hours), and then combine days and hours to one int. Also, if there is a lot of strings probably should parse them just once, create temp struct that has both the string and int, and sort by int, but take the strings in the end.
Thanks for the answer Tim, iam gonna try that out right away! :-)
@MathiasRønnowNørtoft: note that i've edited my answer
@TimSchmelter This seems like what i need, i cant fully test it as of right now. I will do it in the next hour or so and then reply back!
@TimSchmelter when i try using the code, my array variable "i" never gets incremented, so the program never fully runs through the code? any thoughts?
|
0

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..

Comments

0

@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++;



            }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.