Ordine LINQ Per aiuto necessario
-
03-07-2019 - |
Domanda
Sto cercando di creare una raccolta di stringhe in un ordine definito da un altro array. Sembra confuso, lo so, quindi lasciami spiegare
requiredOrderOfElements
{
[0] category1,
[1] categoryX,
[2] something else
}
il mio client passa un array di stringhe contenente la chiave e il valore, cioè
passato dal client
{
[0][0] categoryX,
[0][1] value from Category X,
[1][0] something else,
[1][1] value for something else,
[2][0] category1,
[2][1] value from Category 1
}
quello che voglio è il "valore" testi nell'ordine richiesto delle chiavi
quello che voglio
[0]value from Category 1
[1]value from Category X
[2]value for something else
Ho esaminato OrderBy / IComparer e non riesco a vedere un modo ovvio per implementare ciò di cui ho bisogno. La mia attuale soluzione è un brutto ciclo annidato
Qualsiasi idea per un modo più elegante sarebbe apprezzata.
Aggiornamento: - ecco il test
[TestFixture]
public class GL_Linq_Test
{
[Test]
public void CanOrderByAnotherArray()
{
var requiredOrder=new[]{"my","required","order"};
var passedFromClient = new[]
{
new[] {"required", "cat"},
new[] {"order", "dog"},
new[] {"my", "bird"}
};
var ordered = FunkyOrderer.Order(requiredOrder, passedFromClient);
Assert.That(ordered.First()[1],Is.EqualTo("bird"));
Assert.That(ordered.Skip(1).First()[1], Is.EqualTo("cat"));
Assert.That(ordered.Skip(2).First()[1], Is.EqualTo("dog"));
}
}
public static class FunkyOrderer
{
//returns order bird,dog,cat not bird,cat,dog
public static IEnumerable<string[]> Order(string[] requiredOrder, IEnumerable<string[]>passedFromClient)
{
return from o in requiredOrder
join f in passedFromClient on o equals f[0]
orderby o
select f;
}
}
Soluzione
Il problema è che supponendo che un array di stringhe verrà ordinato dal loro indice (non lo faranno). L'ordine di " my " ;, " order " ;, " richiesto "
è corretto usando il comparatore di stringhe incorporato. La soluzione più semplice è modificare la query LINQ per tenere conto dell'indice al momento dell'ordine.
return from o in requiredOrder.Select((o, i) => new { Value = o, Index = i })
join f in passedFromClient on o.Value equals f[0]
orderby o.Index
select f;
Altri suggerimenti
var orderByThese = new string[] { "category1", "categoryX", "something else" };
var fromClient = new string[][]
{
new string[] { "categoryX", "value from Category X" },
new string[] { "something else", "value for something else" },
new string[] { "category1", "value from Category 1" }
};
var joined = from o in orderByThese
join f in fromClient on o equals f[0]
orderby o
select f;