Reputation: 79
I want to order a List of strings but one string in the list should always be at the last and not sorted. What is the easiest way to do this with LINQ?
//should be ordered in: a,b,u,z, last:
List<string> l = {"z","u","last","b","a"};
There is no append method or something in LINQ, is there?
Upvotes: 1
Views: 1791
Reputation: 18155
Just realized the OP meant the value "last" and not the Last element. In this case, it would be much easier with
var result = l.OrderBy(x => string.Equals(x,"last")).ThenBy(x => x);
Please note the above would require sorting twice.You could also define a Custom Comparer to be used with OrderBy
, and there by skipping multiple OrderBy
public class LastSkipComparer<T> : IComparer<T> where T : IComparable<T>
{
private Func<T,bool> _selector;
public LastSkipComparer(Func<T,bool> selector)
{
_selector = selector;
}
public int Compare(T instanceA, T instanceB)
{
if(_selector(instanceA)) return 1;
if(_selector(instanceB)) return -1;
return instanceA.CompareTo(instanceB);
}
}
Now You could sort as,
var result = l.OrderBy(x=> x,
new LastSkipComparer<string>((val)=> string.Equals(val,"last")));
Sample Output
To order every element, but the last, You could use use SkipLast
, then Order the remaining, followed by Appending the Last Element again. For Example,
List<string> l = new[] {"z","u","last","b","a"}.ToList();
var result = l.SkipLast(1).OrderBy(x=>x).Append(l.Last());
SkipLast : Returns a new enumerable collection that contains the elements from source with the last count elements of the source collection omitted.
Enumerable.Append : Appends a value to the end of the sequence.
Please note SkipLast
require .NET(5.0, 6.0 Preview 3) Or .NET Core( 2.0, 2.1, 2.2, 3.0, 3.1) or .NET Standard 2.1
Sample Output
Upvotes: 2
Reputation: 2490
try this
List<string> l = new List<string>{ "z", "u", "last", "b", "a" };
var k = l.Where(x=>x!="last").OrderBy(x=>x).Append("last");
Upvotes: 1
Reputation: 705
You can use either .Concat()
to add the string that you desire at the end or use .OrderBy()
to place your string at the end while leaving all others in the front and use .ThenBy()
afterwards to sort the items. .ThenBy()
will apply when you the previous orderings provide groups of items that are considered equal.
var list = new List<string> { "z", "u", "last", "b", "a" };
var result = list
.OrderBy(item => item == "last" ? 1 : 0)
.ThenBy(item => item);
Or in place sort
var list = new List<string> { "z", "u", "last", "b", "a" };
list.Sort((left, right) => left == "last" ? 1 : right == "last" ? -1 : string.Compare(left, right));
Using .Concat()
var list = new List<string> { "z", "u", "last", "b", "a" };
var result = list
.Where(item => item != "last")
.OrderBy(item => item)
.Concat(Enumerable.Repeat("last", 1));
Upvotes: 3