vts
vts

Reputation: 1717

Linq Order by a specific number first then show all rest in order

If i have a list of numbers:

1,2,3,4,5,6,7,8

and I want to order by a specific number and then show the rest. For example if i pick '3' the list should be:

3,1,2,4,5,6,7,8

Looking for linq and c#. Thank you

Upvotes: 101

Views: 55732

Answers (6)

sneha shah
sneha shah

Reputation: 75

You can try with below code with list of dynamic string values

var defaultSortingInternalTrades = ["E,F,G"];
    
var ItemsToSort = ["A","B","C","D","E",...];
var fData = items.Where(d => defaultSortingInternalTrades.Contains(d.ToString()))
                 .OrderBy(x => defaultSortingInternalTrades.IndexOf(x.ToString())).ToList();
var oData = items.Where(d => !defaultSortingInternalTrades.Contains(d.ToString())).ToList();
fData.AddRange(oData);

Upvotes: 1

xhafan
xhafan

Reputation: 2406

Using @joachim-isaksson idea I came up with this extension method:

public static IOrderedEnumerable<TSource> OrderByWithGivenValueFirst<TSource, TKey>(
    this IEnumerable<TSource> source, 
    Func<TSource, TKey> keySelector,
    TKey value
    ) 
    => source.OrderBy(x => !keySelector(x).Equals(value));

Test:

[TestFixture]
public class when_ordering_by_with_given_value_first
{
    [Test]
    public void given_value_is_first_in_the_collection()
    {
        var languages = new TestRecord[] {new("cs-CZ"), new("en-US"), new("de-DE"), new("sk-SK")};

        languages.OrderByWithGivenValueFirst(x => x.Language, "en-US")
            .ShouldBe(new TestRecord[] {new("en-US"), new("cs-CZ"), new("de-DE"), new("sk-SK")});

    }

    private record TestRecord(string Language);
}

Upvotes: 0

Tim Schmelter
Tim Schmelter

Reputation: 460098

You can use a comparison in OrderBy or ThenBy to perform a conditional sorting.

list.OrderByDescending(i => i == 3).ThenBy(i => i);

I use OrderByDescending because i want matching results first(true is "higher" than false).

Upvotes: 214

Adrian Iftode
Adrian Iftode

Reputation: 15663

public static IEnumerable<T> TakeAndOrder<T>(this IEnumerable<T> items, Func<T, bool> f)
{       
    foreach ( var item in items.Where(f))
        yield return item;
    foreach (var item in items.Where(i=>!f(i)).OrderBy(i=>i))
        yield return item;
}


var items = new [] {1, 4, 2, 5, 3};
items.TakeAndOrder(i=> i == 4);

Upvotes: 3

Joachim Isaksson
Joachim Isaksson

Reputation: 180917

A couple of answers already sort the last few numbers (which may be correct since you're only showing an already sorted list). If you want the "unselected" numbers to be displayed in their original, not necessarily sorted order instead of sorted, you can instead do;

int num = 3;
var result = list.Where(x => x == num).Concat(list.Where(x => x != num));

As @DuaneTheriot points out, IEnumerable's extension method OrderBy does a stable sort and won't change the order of elements that have an equal key. In other words;

var result = list.OrderBy(x => x != 3);

works just as well to sort 3 first and keep the order of all other elements.

Upvotes: 8

Arion
Arion

Reputation: 31239

Maybe something like this:

List<int> ls=new List<int>{1,2,3,4,5,6,7,8};
int nbr=3;
var result= ls.OrderBy (l =>(l==nbr?int.MinValue:l));

Upvotes: 5

Related Questions