对List <string>进行排序包含坐标x和y </string>

时间:2012-08-11 13:13:19

标签: c# string list sorting split

任何人都可以帮我分类下面的字符串列表:

列表&lt; 字符串&gt;包含坐标

[0]“0 0”
[1]“0 1”
[2]“0 2”
[3]“0 3”
[4]“1 1”
[5]“1 2”
[6]“1 3”

虽然它可能并不总是按照这个顺序,我想通过排序/排序来确定它(按X坐标ASC然后按Y坐标ASC排序)

我试过这个,但它根本没有改变名单? - 见下文

boardObjectList.OrderBy(p => (p.Split())[0]).ThenBy(p=> (p.Split())[1]);

有什么想法吗?

谢谢,
JP

3 个答案:

答案 0 :(得分:5)

OrderByThenBy不会修改原始列表,只会返回一个新列表(以IEnumerable<>的形式)。您需要做的是从生成的List<>中创建一个新的IEnumerable<>,如下所示:

// Note that we are assigning the variable to a new list
boardObjectList = boardObjectList.OrderBy(p => (p.Split())[0])
                                 .ThenBy(p => (p.Split())[1])
                                 .ToList(); // Also note that we call ToList,
                                            // to get a List from an IEnumerable

将数字存储在字符串中并尝试排序时,会得到奇怪的结果。我建议您将代码更改为:

boardObjectList = boardObjectList.OrderBy(p => int.Parse(p.Split()[0]))
                                 .ThenBy(p => int.Parse(p.Split()[1]))
                                 .ToList();

此方法在排序之前将字符串转换为整数。这样做的原因是字符串排序按字母顺序排序,导致排序如下:

1
10
11
12
2
3
4
5
6
7
8
9

答案 1 :(得分:1)

这是一个可能的解决方案。我为整数坐标使用单独的结构,并将拆分字符串转换为该实例。

// Defined elsewhere
struct Coord
{
    public int x;
    public int y;
}


// Where you're doing your work...
var intCoords = new List<Coord>();
foreach (var coord in boardObjectList)
{
    var str = coord.Split(new char[] { ' ' });
    intCoords.Add(new Coord() { 
        x = Int32.Parse(str[0]), 
        y = Int32.Parse(str[1])
    });
}

// Do the actual sort. Ensure you assign the result to a variable
var newCoords = intCoords.OrderBy(x => x.x).ThenBy(x => x.y).ToList();

答案 2 :(得分:0)

当然它根本不会改变列表 - LINQ不会修改底层集合,它只是创建查询。

您将查询结果存储在新列表中的目的是什么:

boardObjectList = boardObjectList.OrderBy(p => (p.Split())[0]).ThenBy(p=> (p.Split())[1]).ToList();
编辑:再看看。你不应该比较那样的字符串 - 如果这些“数字”中的任何一个大于“9”会发生什么?这是更新后的解决方案:

boardObjectList = boardObjectList.Select(p => new { P = p, Split = p.Split() } ).
    OrderBy(x => int.Parse(x.Split[0])).ThenBy(x => int.Parse(x.Split[1])).
    Select(x => x.P).ToList();

EDIT2:您也可以在没有LINQ且内存开销较少的情况下执行此操作:

boardObjectList.Sort((a, b) =>
    {
        // split a and b
        var aSplit = a.Split();
        var bSplit = b.Split();
        // see if there's a difference in first coordinate
        int diff = int.Parse(aSplit[0]) - int.Parse(bSplit[0]);
        if (diff == 0)
        {
            // if there isn't, return difference in the second
            return int.Parse(aSplit[1]) - int.Parse(bSplit[1]);
        }
        // positive if a.x>b.x, negative if a.x<b.x - exactly what sort expects
        return diff;
    });