任何人都可以帮我分类下面的字符串列表:
列表< 字符串>包含坐标
[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
答案 0 :(得分:5)
OrderBy
和ThenBy
不会修改原始列表,只会返回一个新列表(以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;
});