C# 使用 LINQ 将项目移动到列表顶部
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1668451/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Use LINQ to move item to top of list
提问by qui
Is there a way to move an item of say id=10 as the first item in a list using LINQ?
有没有办法使用 LINQ 将 id=10 的项目作为列表中的第一项移动?
Item A - id =5 Item B - id = 10 Item C - id =12 Item D - id =1
In this case how can I elegantly move Item C to the top of my List<T>
collection?
在这种情况下,我如何优雅地将项目 C 移动到我的List<T>
收藏的顶部?
This is the best I have right now:
这是我现在最好的:
var allCountries = repository.GetCountries();
var topitem = allCountries.Single(x => x.id == 592);
var finalList = new List<Country>();
finalList.Add(topitem);
finalList = finalList.Concat(allCountries.Where(x=> x.id != 592)).ToList();
采纳答案by JaredPar
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.
LINQ 在查询集合、在现有查询上创建投影或基于现有集合生成新查询方面非常强大。它并不意味着作为内联重新排序现有集合的工具。对于这种类型的操作,最好使用手头的类型。
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;
回答by Grizzly
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)
Linq 通常在 Enumerables 上工作,所以现在它不是底层类型是一个集合。因此,为了将项目移到列表顶部,我建议使用类似的东西(如果您需要保留顺序)
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
如果您的函数只返回一个 IEnumerable,您可以先使用该ToList()
方法将其转换为 List
If you don't preserve the order you can simply swap the values at position 0 and position idx
如果您不保留顺序,您可以简单地交换位置 0 和位置 idx 处的值
回答by Jon Skeet
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:
不可否认,我不知道这在 LINQ to SQL 等中有什么作用。您可能需要阻止它在数据库中进行排序:
var query = allCountries.AsEnumerable()
.OrderBy(x => x.id != 592)
.ToList();
回答by configurator
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.
就复杂性而言,我认为它会对集合进行两次传递,使其成为 O(n),就像插入/删除版本一样,但比 Jon Skeet 的 OrderBy 建议更好。
回答by Grozz
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;
}
回答by Adeola Ojo Gabriel
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);
回答by Gaotter
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
数字是 10
数字是 1
数字是 5
数字是 12
回答by Filip
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 ));
回答by Nick Gillum
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.
这将在列表顶部插入 id=12 的对象并将其余对象向下旋转,保留顺序。
回答by Slai
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();