Use LINQ to move item to top of list

前端 未结 11 1367
轻奢々
轻奢々 2020-12-02 12:00

Is there a way to move an item of say id=10 as the first item in a list using LINQ?

Item A - id =5
Item B - id = 10
Item C - id =12
Item D - id =1

In th

相关标签:
11条回答
  • 2020-12-02 12:24

    To also check if the item was found without Exception, something like:

    var allCountries = repository.GetCountries();
    var lookup = allCountries.ToLookup(x => x.id == 592);  
    var finalList = lookup[true].Concat(lookup[false]).ToList();
    if ( lookup[true].Count() != 1 ) YouAreInTrouble();
    
    0 讨论(0)
  • 2020-12-02 12:25

    I wrote a static extension method to do this. Note this doesn't preserve the order, it simply swaps the item out. If you needed to preserve the order you should do a rotate not a simple swap.

    /// <summary>
    /// Moves the item to the front of the list if it exists, if it does not it returns false
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="collection"></param>
    /// <param name="predicate"></param>
    /// <returns></returns>
    public static bool MoveToFrontOfListWhere<T>(this List<T> collection, Func<T, bool> predicate)
    {
        if (collection == null || collection.Count <= 0) return false;
    
        int index = -1;
        for (int i = 0; i < collection.Count; i++)
        {
            T element = collection.ElementAt(i);
            if (!predicate(element)) continue;
            index = i;
            break;
        }
    
        if (index == -1) return false;
    
        T item = collection[index];
        collection[index] = collection[0];
        collection[0] = item;
        return true;
    }
    
    0 讨论(0)
  • 2020-12-02 12:27
    var allCountries = repository.GetCountries();
    allCountries.OrderByDescending(o => o.id == 12).ThenBy(o => o.id) 
    

    This will insert the object with id=12 at the top of the list and rotate the rest down, preserving the order.

    0 讨论(0)
  • 2020-12-02 12:32

    Linq generallyworks on Enumerables, so it doesn't now that the underlying type is a collection. So for moving the item on top of the list I would suggest using something like (if you need to preserve the order)

    var idx = myList.FindIndex(x => x.id == 592);
    var item = myList[idx];
    myList.RemoveAt(idx);
    myList.Insert(0, item);
    

    If your function returns only an IEnumerable, you can use the ToList() method to convert it to a List first

    If you don't preserve the order you can simply swap the values at position 0 and position idx

    0 讨论(0)
  • 2020-12-02 12:32

    I know this a old question but I did it like this

    class Program
    {
        static void Main(string[] args)
        {
            var numbers = new int[] { 5, 10, 12, 1 };
    
            var ordered = numbers.OrderBy(num => num != 10 ? num : -1);
    
            foreach (var num in ordered)
            {
                Console.WriteLine("number is {0}", num);
            }
    
            Console.ReadLine();
        }
    }
    

    this prints:

    number is 10
    number is 1
    number is 5
    number is 12

    0 讨论(0)
  • 2020-12-02 12:33

    You can "group by" in two groups with Boolean key, and then sort them

    var finalList= allCountries
                    .GroupBy(x => x.id != 592)
                    .OrderBy(g => g.Key)
                    .SelectMany(g => g.OrderBy(x=> x.id ));
    
    0 讨论(0)
提交回复
热议问题