Требуется помощь LINQ OrderBy
-
03-07-2019 - |
Вопрос
Я пытаюсь создать коллекцию строк в порядке, определенном другим массивом.Звучит запутанно, я знаю, так что позвольте мне объяснить
Требуемый порядок элементов
{
[0] category1,
[1] categoryX,
[2] something else
}
мой клиент передает строковый массив, содержащий ключ и значение, т.е.
передано от клиента
{
[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
}
то, что я хочу, - это тексты "значений" в требуемом порядке расположения ключей
чего я хочу
[0]value from Category 1
[1]value from Category X
[2]value for something else
Я просмотрел OrderBy / IComparer и не вижу очевидного способа реализовать то, что мне нужно.Мое текущее решение - это уродливый вложенный цикл for
Будем признательны за любые идеи по созданию более элегантного образа.
Обновить:- вот этот тест
[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;
}
}
Решение
Проблема в том, что вы предполагаете, что массив строк будет упорядочен по их индексу (они этого не сделают).Порядок проведения "my", "order", "required"
корректно использовать встроенный компаратор строк.Самое простое решение - изменить ваш запрос LINQ, чтобы учитывать индекс при оформлении заказа.
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;
Другие советы
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;