【问题标题】:Sort list data from left to right for multiple lines从左到右为多行排序列表数据
【发布时间】:2019-07-17 10:00:08
【问题描述】:

我正在研究 aforge。我有一个我在 blob 旁边的屏幕上绘制的数据列表。我还将数据添加到列表框中。但不是按照从左到右的顺序添加,而是按照 blob 的 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 coord = new List{80,90,100,60,70,20,40,30,10,50,} 如果用户输入 int 行为 2,则输出应为 {60,70,80,90,100,10 ,20,30,40,50} 我该怎么做?

【问题讨论】:

  • 行号和int应该是一个类的两个属性。然后OrderBy(z => z.LineNumber).ThenBy(z => z.IntProperty).

标签: c# linq sorting arraylist aforge


【解决方案1】:

如果您没有代表您的Line 对象的特殊类,那么您可以使用regex 来解析字符串。在这种情况下,我使用name capture group of 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();

或与 fluent 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;
    }
}

此代码取自this answer

那么你使用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 是你的朋友。

【讨论】:

  • 嗨,我收到一个错误,即 regex.Match(string) 有一些无效参数。还有,什么是e?
  • 我在 Linq 中也遇到同样的错误 - regex.Match(string) 有一些无效参数
  • @Roshan, e 是您的elements 列表中的一个元素。我没有regex.Match(string)。我有regex.Match(e)
  • 我在一个按钮中执行这个,所以 e 是 eventargs。如果我用另一个字母代替它,它会给我那个错误,说不能从 int 转换为字符串。
  • 元素中的数据是int
猜你喜欢
  • 2019-09-27
  • 1970-01-01
  • 1970-01-01
  • 2022-06-18
  • 1970-01-01
  • 2021-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多