Dezzamondo
Dezzamondo

Reputation: 2318

Sort list where specific character exists within string

Here's a hypothetical for you. If you were to have a list of strings, is it possible to rank that list by a given character existing within that string?

Consider this pseudo-code:

List<String> bunchOfStrings = new List<String>;
bunchOfStrings.Add("This should not be at the top");
bunchOfStrings.Add("This should not be at the top either");
bunchOfStrings.Add("This should also not be at the top");
bunchOfStrings.Add("This *SHOULD be at the top");
bunchOfStrings.Add("This should not be at the top");
bunchOfStrings.Add("This should be *somewhere close to the top");

buncOfStrings.OrderBy(x => x.Contains("*"));

In the above code, I want to re-order the list so that whenever an asterisk (*) appears within the string, it puts that string at the top of the list.

Any ideas if this is even possible with LINQ or similar?

Upvotes: 3

Views: 2452

Answers (2)

James
James

Reputation: 82096

Assuming you want to prioritise strings based on the position of *, you could do

bunchOfStrings.OrderByDescending(x => x.IndexOf("*"))

Use OrderByDescending because for the strings that don't contain * they will return -1.


Actually, looking further into this it's not going to work straight out the box with IndexOf. OrderByDescending will work by going for the highest ranked index, which in your case is going to be this should be *somewhere close to the top rather than this *SHOULD be at the top because the * has a higher index in that string.

So to get it to work you just need to manipulate the rankings a little and use OrderBy instead

bunchOfStrings.OrderBy(x => {
    var index = x.IndexOf("*");
    return index < 0 ? 9999 : index;
});

Note - 9999 is just some aribtrary value that we can assume IndexOf will never exceed

See live example

Upvotes: 14

Simon Whitehead
Simon Whitehead

Reputation: 65049

If Contains is what you want to use..

Contains returns boolean - so you're ordering by true or false. Since true is 1 and 0 is false - you're ordering them backwards from what you want. So you want OrderByDescending:

bunchOfStrings.OrderByDescending(x => x.Contains("*"))

Which sorts 1 -> 0.

Click here for live example on IDEOne.

Upvotes: 2

Related Questions