Imaginemos que tenemos una lista de cadenas var listA = new List<string> {"B", "C", "A"} , y está ordenada de la manera deseada. Y, hay un objeto definido como:
public class Sample { public string Letter {get;set;} // "A","B","C","D","#" public string Number {get;set;} // not relevant } Además, hay otra lista, List<Sample> listB , y quiero ordenarla de manera que primero vengan objetos con valores de letras "B", luego "C" y al final, "A", para respetar lo mismo orden como está en la listaA. ¿Algunas ideas? :)
EDITAR: la propiedad de letra puede tener una gama más amplia de caracteres, a diferencia de listA, que puede tener solo esos 3. Orden esperado "B", "C", "A" ... "todo el resto, orden no relevante"
Suponga que el valor de Letter está dentro de listA . Vale la pena considerar rediseñar el algoritmo si la suposición es falsa. Y puede depender del requisito del orden esperado los fuera de rango.
var sortedSamples = listB.OrderBy(x=>listA.IndexOf(x.Letter));Para un mejor rendimiento, almacene en caché las órdenes en un diccionario:
var orders = new Dictionary<string, int>(); for (int i = 0; i < listA.Count; i++) { orders.Add(listA[i], i); } var sortedSamples = listB.OrderBy(x=>orders[x.Letter]); Si el rango de valores posibles de Letter es mucho más pequeño que listA , entonces es mejor construir orders como esta:
foreach (string letter in listB.Select(x=>x.Letter)) { orders.Add(letter, listA.IndexOf(letter)); }Actualizar
Si el rango de letters está fuera de listA , y como OP quiere que las letras estén al final:
var orders = new Dictionary<string, int>(); for (int i = 0; i < listA.Count; i++) { orders.Add(listA[i], i); } int lastIndex = listA.Count; foreach (string letter in listB.Select(x=>x.Letter) .Distinct().Except(listA)) { orders.Add(letter, lastIndex); }Deberías usar algo como esto
var listA = new List<string> { "B", "C", "A" }; var listB = new List<string> { "A", "B", "C" }; listB = listB.OrderBy(d => listA.IndexOf(d)).ToList(); // listB: "B", "C", "A"Puede usar esta extensión que también admite la comparación de las entradas en las listas por una propiedad específica (por ejemplo, id en lugar de referencia)
public static IEnumerable<TFirst> OrderBy<TFirst, TSecond, TKey>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TKey> firstKeySelector, Func<TSecond, TKey> secondKeySelector) => second .Join( first, secondKeySelector, firstKeySelector, (_, firstItem) => firstItem); esto ordenará los elementos en second de la misma manera que ya están ordenados en first lugar comparándolos con ambos selectores clave.
Tenga en cuenta que esto solo funciona si TODAS las claves en el first también están presentes en el second .