LINQ OrderBy ajuda necessária
-
03-07-2019 - |
Pergunta
Eu estou tentando criar uma coleção de strings em uma ordem definida por outra matriz. Parece confuso eu sei então deixe-me explicar
requiredOrderOfElements
{
[0] category1,
[1] categoryX,
[2] something else
}
meu cliente passa-se uma matriz de cadeia que contém a chave e valor ie
passou de cliente
{
[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
}
o que eu quero, é o "valor" textos na ordem necessária das chaves
o que eu quero
[0]value from Category 1
[1]value from Category X
[2]value for something else
Eu olhei OrderBy / IComparer e não pode ver uma maneira óbvia para implementar o que eu preciso. Minha solução atual é um feio nested loop for
Todas as idéias para uma maneira mais elegante seria apreciada.
Update: - aqui é o teste
[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;
}
}
Solução
O problema é que você assumindo uma matriz de strings serão ordenados por seu índice (que não). A ordem de "my", "order", "required"
está correto usando o construído em comparer string. A solução mais fácil é modificar sua consulta LINQ para levar o índice em conta quando ordenação.
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;
Outras dicas
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;