3

誰でも次の文字列のリストをソートするのを手伝ってくれませんか:

List< String > には座標が含まれています

[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

4

3 に答える 3

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
于 2012-08-11T13:22:37.033 に答える
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();
于 2012-08-11T14:05:16.433 に答える
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;
    });
于 2012-08-11T13:18:05.723 に答える