Use LINQ to move item to top of list

前端 未结 11 1368
轻奢々
轻奢々 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:34

    What do you want to order by, other than the known top item? If you don't care, you can do this:

    var query = allCountries.OrderBy(x => x.id != 592).ToList();
    

    Basically, "false" comes before "true"...

    Admittedly I don't know what this does in LINQ to SQL etc. You may need to stop it from doing the ordering in the database:

    var query = allCountries.AsEnumerable()
                            .OrderBy(x => x.id != 592)
                            .ToList();
    
    0 讨论(0)
  • 2020-12-02 12:35

    LINQ is strong in querying collections, creating projections over existing queries or generating new queries based on existing collections. It is not meant as a tool to re-order existing collections inline. For that type of operation it's best to use the type at hande.

    Assuming you have a type with a similar definition as below

    class Item {
      public int Id { get; set; }
      ..
    }
    

    Then try the following

    List<Item> list = GetTheList();
    var index = list.FindIndex(x => x.Id == 12);
    var item = list[index];
    list[index] = list[0];
    list[0] = item;
    
    0 讨论(0)
  • 2020-12-02 12:37
    public static IEnumerable<T> ServeFirst<T>(this IEnumerable<T> source, 
        Predicate<T> p)
    {
        var list = new List<T>();
    
        foreach (var s in source)
        {
            if (p(s))
                yield return s;
            else
                list.Add(s);
        }
    
        foreach (var s in list)
            yield return s;
    }
    
    0 讨论(0)
  • 2020-12-02 12:38

    Its interesting the number of approaches you find when trying to solve a problem.

    var service = AutogateProcessorService.GetInstance();
    var allConfigs = service.GetAll();
    allConfigs = allConfigs.OrderBy(c => c.ThreadDescription).ToList();
    var systemQueue = allConfigs.First(c => c.AcquirerId == 0);
    allConfigs.Remove(systemQueue);
    allConfigs.Insert(0, systemQueue);
    
    0 讨论(0)
  • 2020-12-02 12:41

    Here is an extension method you might want to use. It moves the element(s) that match the given predicate to the top, preserving order.

    public static IEnumerable<T> MoveToTop(IEnumerable<T> list, Func<T, bool> func) {
        return list.Where(func)
                   .Concat(list.Where(item => !func(item)));
    }
    

    In terms of complexity, I think it would make two passes on the collection, making it O(n), like the Insert/Remove version, but better than Jon Skeet's OrderBy suggestion.

    0 讨论(0)
提交回复
热议问题