DOBON.NET DOBON.NETプログラミング掲示板過去ログ

構造体配列のソート

  • 題名: 構造体配列のソート
  • 著者: 鶏唐揚
  • 日時: 2008/04/21 15:07:45
  • ID: 21894
  • この記事の返信元:
    • (なし)
  • この記事への返信:
  • ツリーを表示
環境/言語:[WindowsXP/VB.NET2003]
分類:[.NET]

お久しぶりですお世話になってます。

今回、構造体配列のソートについて質問させていただきます。
ある構造体TESTには、A、B、Cというメンバがあるとします。
ここで、Aの昇順・Bの昇順 で並べ替えたいと思います。
SQLでいうとこの「ORDER BY A, B」というものです。

全部自前でやるには相当なコーディングが必要なのと、
今回データ件数がかなり多くて速度的に心配なので、
メソッドか何かで一発でできる方法があればご教示願います。

同じような質問は多数見つけたのですが、どれも解決に至ってないようなので
新規にて質問させていただきました。よろしくお願いします
http://hpcgi1.nifty.com/MADIA/vbnet/wwwlng.cgi?print+200712/07120009.txt
は参考にならないでしょうか?
■No21895に返信(永遠の近鉄ファンさんの記事)
> http://hpcgi1.nifty.com/MADIA/vbnet/wwwlng.cgi?print+200712/07120009.txt
> は参考にならないでしょうか?
>
返信ありがとうございます。参考にさせていただきます。

ただ今回、実際の構造体のメンバ数は実に52にも及ぶものなので
.Row.Addがかなり長いことになりそうですが、試して見ます。
構造体を使っているところで、クラスに変えられるなら、こんなんもあります。
IComparableを継承して、CompareToを実装してあげて、その上で、
中身を書いてあげれば、あとはArrayListのSortなんかで、自分の思うがままに
ソート処理が実装できます。
構造体をクラスに変えろといっているようなものなので、今更ですがorz
遅くなりました
>ただ今回、実際の構造体のメンバ数は実に52にも及ぶものなので
>.Row.Addがかなり長いことになりそうですが、試して見ます。
永遠の近鉄ファンさんのリンク先では.Rows.Addの引数に各列項目をとっていたので、
同じように5項目くらいまで書いてみたのですが、引数を解決できるオーバーロードを
見つけられないとか何とかでだめでした…再度リンク先とRowsに関するリファレンスを熟読して試してみます。
一応、独自ロジックでのソートも完成させましたがテスト不足で不安なので
引き続きDataTableの方法を模索してみます。

■No21901に返信(じゅでさんの記事)
> 構造体を使っているところで、クラスに変えられるなら、こんなんもあります。
> IComparableを継承して、CompareToを実装してあげて、その上で、
> 中身を書いてあげれば、あとはArrayListのSortなんかで、自分の思うがままに
> ソート処理が実装できます。
> 構造体をクラスに変えろといっているようなものなので、今更ですがorz
今回はソート処理以外の部分はもう完成してしまっているので、構造体のままがんばってみます。
クラスの方法は次回に応用させていただきます。ありがとうございます。
2008/04/23(Wed) 10:05:15 編集(投稿者)

いろいろ調べた結果、下記のようにして実現できました。

'---------------------------------------------------
Dim TestData() As TEST

Dim SortTable As DataTable
Dim nrow As DataRow

Dim i As Integer

'[省略]TestData配列のデータ内容作成

SortTable = New DataTable("SortTable")

'列作成
With SortTable.Column
    .Add("dataA")
    .Add("dataB")
    .Add("dataC")
End With

'DataTableにぶちこむ
For i = 0 To TestData.Length - 1
    nrow = SortTable.NewRow()
    
    nrow("dataA") = TestData(i).A
    nrow("dataB") = TestData(i).B
    nrow("dataC") = TestData(i).C
    SortTable.Rows.Add(nrow)
Next

'ソート
SortTable.DefaultView.Sort() = "dataA ASC, dataB ASC"

'構造体配列に戻す
For i = 0 To TestData.Length - 1
    With TestData(i)
        .A = SortTable.Rows(i).Item("dataA")
        .B = SortTable.Rows(i).Item("dataB")
        .C = SortTable.Rows(i).Item("dataC")
    End If
Next

'後処理は省略
'---------------------------------------------------
一応当初の目的は実現できたので、解決済みにしておきますが、
永遠の近鉄ファンさんの提示していただいたリンク先の方法で
できなかったのは謎なままなので情報提供待っています。
解決済み!
鶏唐揚さんはわんくま掲示板でよく見る鶏唐揚さんと同一人物なのかしら。
(あ、ちょっと気になっただけです。お気を悪くしないでください)

■No21910に返信(鶏唐揚さんの記事)

> 'ソート
> SortTable.DefaultView.Sort() = "dataA ASC, dataB ASC"
> 
> '構造体配列に戻す
> For i = 0 To TestData.Length - 1
>     With TestData(i)
>         .A = SortTable.Rows(i).Item("dataA")
>         .B = SortTable.Rows(i).Item("dataB")
>         .C = SortTable.Rows(i).Item("dataC")
>     End If
> Next

ここですが、ソートしたのであればソート後の DataView を
利用して

> 'ソート
> SortTable.DefaultView.Sort() = "dataA ASC, dataB ASC"
> 
> '構造体配列に戻す
> For i = 0 To TestData.Length - 1
>     With TestData(i)
>         .A = SortTable.DefaultView(i).Item("dataA")
>         .B = SortTable.DefaultView(i).Item("dataB")
>         .C = SortTable.DefaultView(i).Item("dataC")
>     End If
> Next

こんな感じになるんじゃないでしょうか。

# 個人的には DataTable に変換する手間を考えると、じゅでさんの
# 方式が素直なような気がしますね
解決済み!
  • 題名: Re[7]: 構造体配列のソート
  • 著者: 鶏唐揚
  • 日時: 2008/04/23 10:45:57
  • ID: 21913
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
■No21912に返信(ぽぴ王子さんの記事)
> 鶏唐揚さんはわんくま掲示板でよく見る鶏唐揚さんと同一人物なのかしら。
> (あ、ちょっと気になっただけです。お気を悪くしないでください)
はいそうです。

> こんな感じになるんじゃないでしょうか。
今確認したら全くその通りでございました。
動いたというだけでデータ整合性チェックしてなかったです…
大変失礼しましたorz

> # 個人的には DataTable に変換する手間を考えると、じゅでさんの
> # 方式が素直なような気がしますね
今回は先述の通り、構造体から変えるほうが手間とリスクが伴うので
仕方なくDataTable使いました。
私もクラスで管理したほうが楽なので次回以降はじゅでさんの方法で
やっていきたいと思います


#謎解けました。リンク先はVB2005で私はVB2003。気になって調べたら
 VB2005からROws.Addの引数がParamArrayになっていたのですね。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板