LINQ OrderPar aide nécessaire
-
03-07-2019 - |
Question
J'essaie de créer une collection de chaînes dans un ordre défini par un autre tableau. Cela semble déroutant, alors laissez-moi vous expliquer.
requiredOrderOfElements
{
[0] category1,
[1] categoryX,
[2] something else
}
mon client transmet un tableau de chaînes contenant la clé et la valeur, par exemple
passé du 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
}
Ce que je veux, c'est la "valeur" textes dans l'ordre requis des touches
ce que je veux
[0]value from Category 1
[1]value from Category X
[2]value for something else
J'ai examiné OrderBy / IComparer et je ne vois pas de façon évidente de mettre en œuvre ce dont j'ai besoin. Ma solution actuelle est une boucle for imbriquée moche
Toutes les idées pour une manière plus élégante seraient appréciées.
Mise à jour: - voici le 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;
}
}
La solution
Le problème est que vous supposez qu'un tableau de chaînes sera ordonné par son index (elles ne le seront pas). L’ordre de "my", "order", "required"
est correct à l’aide du comparateur intégré. La solution la plus simple consiste à modifier votre requête LINQ pour prendre en compte l’index lors de la commande.
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;
Autres conseils
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;