LINQ OrderBy Hilfe benötigt
-
03-07-2019 - |
Frage
Ich versuche, eine Sammlung von Zeichenketten in einer Reihenfolge von einem anderen Array definiert zu erstellen. Klingt verwirrend ich weiß, lassen Sie mich so erklären
requiredOrderOfElements
{
[0] category1,
[1] categoryX,
[2] something else
}
meine Client übergibt einen String-Array enthält den Schlüssel und Wert dh bis
vom Client übergeben
{
[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
}
, was ich will, ist der „Wert“ Texte in der gewünschten Reihenfolge der Tasten
, was ich will
[0]value from Category 1
[1]value from Category X
[2]value for something else
Ich habe bei SortiertNach / IComparer sieht und kann nicht eine offensichtliche Art und Weise sehen zu implementieren, was ich brauche. Meine aktuelle Lösung ist eine hässliche verschachtelte for-Schleife
Alle Ideen für eine elegantere Art und Weise geschätzt würde.
Update: - Hier ist der 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;
}
}
Lösung
Das Problem ist, dass Sie ein Array von Strings unter der Annahme wird durch ihren Index bestellt werden (sie werden nicht). Die Reihenfolge der "my", "order", "required"
ist korrekt mit dem in String comparer gebaut. Die einfachste Lösung ist Ihre LINQ-Abfrage zu ändern, um den Index zu berücksichtigen, bei der Bestellung.
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;
Andere Tipps
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;