Utiliser LINQ pour déplacer l’élément en haut de la liste

Existe-t-il un moyen de déplacer un élément de say id = 10 en tant que premier élément d’une liste en utilisant LINQ?

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

Dans ce cas, comment puis-je déplacer élégamment l’élément C en haut de ma collection List ?

C’est le meilleur que j’ai maintenant:

 var allCounsortinges = repository.GetCounsortinges(); var topitem = allCounsortinges.Single(x => x.id == 592); var finalList = new List(); finalList.Add(topitem); finalList = finalList.Concat(allCounsortinges.Where(x=> x.id != 592)).ToList(); 

LINQ est fort en matière d’interrogation de collections, de création de projections sur des requêtes existantes ou de génération de nouvelles requêtes basées sur des collections existantes. Il ne s’agit pas d’un outil permettant de réorganiser des collections existantes en ligne. Pour ce type d’opération, il est préférable d’utiliser le type à hande.

En supposant que vous avez un type avec une définition similaire à celle ci-dessous

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

Ensuite, essayez ce qui suit

 List list = GetTheList(); var index = list.FindIndex(x => x.Id == 12); var item = list[index]; list[index] = list[0]; list[0] = item; 

De quoi voulez-vous commander, autre que l’élément connu? Si vous vous en fichez, vous pouvez le faire:

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

Fondamentalement, “faux” vient avant “vrai” …

Certes, je ne sais pas ce que cela fait dans LINQ to SQL, etc. Vous devrez peut-être l’empêcher de commander dans la firebase database:

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

Linq généralement fonctionne sur Enumerables, donc ce n’est pas maintenant que le type sous-jacent est une collection. Donc, pour déplacer l’élément en haut de la liste, je suggérerais d’utiliser quelque chose comme (si vous devez conserver la commande)

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

Si votre fonction ne renvoie qu’un IEnumerable, vous pouvez utiliser la méthode ToList() pour la convertir d’abord en une liste

Si vous ne conservez pas la commande, vous pouvez simplement échanger les valeurs en position 0 et en position idx

 var allCounsortinges = repository.GetCounsortinges(); allCounsortinges.OrderByDescending(o => o.id == 12).ThenBy(o => o.id) 

Cela va insérer l’object avec id = 12 en haut de la liste et faire pivoter le rest, en préservant l’ordre.

Voici une méthode d’extension que vous pouvez utiliser. Il déplace les éléments correspondant au prédicat donné vers le haut, en préservant l’ordre.

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

En termes de complexité, je pense que cela ferait deux passages sur la collection, ce qui la rendrait O (n), comme la version Insert / Remove, mais meilleure que la suggestion OrderBy de Jon Skeet.

Vous pouvez “grouper par” en deux groupes avec une clé booléenne, puis les sortinger

 var finalList= allCounsortinges .GroupBy(x => x.id != 592) .OrderBy(g => g.Key) .SelectMany(g => g.OrderBy(x=> x.id )); 
 public static IEnumerable ServeFirst(this IEnumerable source, Predicate p) { var list = new List(); foreach (var s in source) { if (p(s)) yield return s; else list.Add(s); } foreach (var s in list) yield return s; } 

C’est intéressant le nombre d’approches que vous trouvez lorsque vous essayez de résoudre un problème.

 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); 

Je sais que c’est une vieille question mais je l’ai fait comme ça

 class Program { static void Main(ssortingng[] 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(); } } 

ceci imprime:

le nombre est 10
le nombre est 1
le nombre est 5
le nombre est 12

Pour vérifier également si l’élément a été trouvé sans exception, quelque chose comme:

 var allCounsortinges = repository.GetCounsortinges(); var lookup = allCounsortinges.ToLookup(x => x.id == 592); var finalList = lookup[true].Concat(looup[false]).ToList(); if ( lookup[true].Count != 1 ) YouAreInTrouble(); 

J’ai écrit une méthode d’extension statique pour ce faire. Notez que cela ne préserve pas l’ordre, il échange simplement l’élément. Si vous deviez conserver la commande, vous devriez faire une rotation et non un simple échange.

 ///  /// Moves the item to the front of the list if it exists, if it does not it returns false ///  ///  ///  ///  ///  public static bool MoveToFrontOfListWhere(this List collection, Func 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; }