Сортировать данные списка слева направо по нескольким строкам - PullRequest
0 голосов
/ 23 февраля 2019

Я работаю над aforge.У меня есть список данных, которые я рисую на экране рядом с каплями.Я также добавляю данные в список.Но вместо добавления в последовательности слева направо добавляется в соответствии с координатой XY большого двоичного объекта, как показано ниже в первом списке.

enter image description here

Я попытался отсортировать список с помощью 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);                
        }

Если список координат = новыйСписок {80,90,100,60,70,20,40,30,10,50}, если пользовательский ввод int строка равен 2, то вывод должен быть {60,70,80,90,100,10,20,30,40,50} Как я могу это сделать?

1 Ответ

0 голосов
/ 23 февраля 2019

Если у вас нет специального класса, представляющего ваш объект 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 - это вашдруг.

...