Сортировать данные списка слева направо по нескольким строкам
Я работаю над Aforge. У меня есть список данных, которые я рисую на экране рядом с каплями. Я также добавляю данные в список. Но вместо того, чтобы быть добавленным в последовательности слева направо, он добавляется в соответствии с координатой XY большого двоичного объекта, как показано ниже в первом списке.
Я попытался отсортировать список с помощью Linq методом OrderBy, но затем он упорядочил весь список в порядке возрастания. Я не хочу этого, я хочу, чтобы список сортировался по первой строке, затем по следующей строке и так далее. Я попытался использовать take<>, чтобы отсортировать его по первой строке, но он сортирует только первую строку по 5 int, а затем останавливается.
Код:
int n = 5;
elements = elements.Take(n).OrderBy(i => i).ToList();
foreach (var cogxx in elements)
{
listBox2.Items.Add(cogxx);
}
Если List координировать = новый список {80,90,100,60,70,20,40,30,10,50,}, если пользовательский ввод int строка равен 2, то вывод должен быть {60,70,80,90,100,10,20,30,40,50} Как я могу это сделать?
1 ответ
Если у вас нет специального класса, представляющего ваш Line
объект, то вы можете использовать regex
разобрать строку. В этом случае я использую name capture group
из Regex
:
List<string> elements = new List<string>
{
"Line 1 int 1",
"Line 2 int 1",
"Line 1 int 2",
"Line 1 int 3",
"Line 2 int 2",
"Line 2 int 12",
};
var pattern = @"^\bLine \b(?<num1>\d+) \bint \b(?<num2>\d+)$";
Regex regex = new Regex(pattern);
var query =
from e in elements
where regex.Match(e).Success
orderby
int.Parse(regex.Match(e).Groups["num1"].Value),
int.Parse(regex.Match(e).Groups["num2"].Value)
select e;
var orderedResult = query.ToList();
Или то же самое с беглым API LINQ:
var orderedResult =
elements
.Where(e => regex.Match(e).Success)
.OrderBy(e => int.Parse(regex.Match(e).Groups["num1"].Value))
.ThenBy(e => int.Parse(regex.Match(e).Groups["num2"].Value))
.ToList();
orderedResult
должно быть:
Line 1 int 1
Line 1 int 2
Line 1 int 3
Line 2 int 1
Line 2 int 2
Line 2 int 12
ОБНОВИТЬ:
Создайте методы класса и расширения, которые разбили бы ваш список на куски:
public static class MyLinqExtensions
{
public static IEnumerable<IEnumerable<T>> Batch<T>(
this IEnumerable<T> source, int batchSize)
{
using (var enumerator = source.GetEnumerator())
while (enumerator.MoveNext())
yield return YieldBatchElements(enumerator, batchSize - 1);
}
private static IEnumerable<T> YieldBatchElements<T>(
IEnumerator<T> source, int batchSize)
{
yield return source.Current;
for (int i = 0; i < batchSize && source.MoveNext(); i++)
yield return source.Current;
}
}
Этот код был взят из этого ответа.
Тогда вы используете Batch
метод расширения следующим образом:
List<int> coord = new List<int> { 80, 90, 100, 60, 70, 20, 40, 30, 10, 50 };
int n = 5;
var orderedResult =
coord.Batch(n)
.Select(b => b.OrderBy(i => i))
.SelectMany(x => x)
.ToList();
Если вы хотите изучать LINQ, LINQPad - ваш друг.