みなさんこんにちは!
ヒロポンです!
C#ではおなじみのDataTableですが、Linqを使えば1行で分割できるのご存知でしたか??
今回はC#でDatatabeを指定の列ごとに分割する方法について書いていきたいと思います!
C#でDataTable指定の列で分割!
いかのようなデータがあった場合。
Id | 売れたもの | 買った人 |
1 | りんご | Aさん |
2 | りんご | Bさん |
3 | みかん | Cさん |
4 | みかん | Bさん |
5 | なし | Aさん |
6 | りんご | Aさん |
7 | りんご | Cさん |
8 | なし | Bさん |
9 | みかん | Aさん |
10 | なし | Cさん |
下記のようなコードで分割をすることができます。
DataTable dt = 上記のテーブル
DataTable[] dts = dt.AsEnumerable().GroupBy(r => r.Field<string>("売れたもの")).Select(r => r.CopyToDataTable());
どうです??
簡単でしょう??
複数の列で分割する場合は下記のようにすれば行けます。
var dts = dt.AsEnumerable()
.GroupBy(r => new{group1 = r.Field<string>("売れたもの"),
group2 = r.Field<string>("買った人") })
.Select(r => r.CopyToDataTable());
これで満足できた人は、このタイミングでページを閉じていただいてもかまいません!
下記では、1行コードの中身について、解説していきまます!
C#のLinqのGroupByの戻り値は?
さて!1行でDataTableを分割できたわけなのですが、このコードの中身どうなっているのでしょうか?
見ていきましょう!
まずは、AsEnumerable()ですが、これはDataTableをLinqで扱う際の決まり文句といえます。
続いてGroupBy()の中身ですが、これの戻り値は下記のようになっています。
IEnumerable<IGrouping<string,DataRow>>
IEnumerable<IGrouping<グルーピングのキー,DataRowの配列>>
すなわち、このタイミングで以下の事をしているということができるといえます。
- 指定の列の値でGroupingしている。
- GroupingしたDataRowをキーごとに持っている。
ということは、IGroupingごとに、再度Loopをしてデータテーブルを作っていけば、Groupで分けたDatarowをDatatableに再構築することができます。
それが下記です。
C#でIGroupingをDatatableに再構築
IGroupingは中にGroupのキーとDataRowを持っているといいました。
ではこのDataRowをDatatableに再構築すれば、当初の予定だったDatatableをLinqを用いて列ごとに分割するということが達成できます。
IGroupingはIEnumerableを継承しています。
ということは、Linqが使えます。
ということで、こうしましょう。
IEnumerable<IGrouping<string,DataRow>> groupRows = dt.AsEnumerable().GroupBy(r => r.Field<string>("買ったもの"));
IEnumerable<DataTable> dts = groupRows.Select(r => r.CopyToDataTable());
IGroupingをそのままCopyToDataTableでDataTableにコピーして、どんどんとテーブルを作って行きます。
以上
おまけ(Whereで条件を絞ったテーブルを新たに作成)
今回はGroupByで列ごとにデータを分割してDatatableを新たに作るということをしましたが、Linqを使えば下記のようなこともできます。
var whereDt = dt.AsEnumerable().Where(r => r.Field<string>("買ったもの") == "リンゴ").CopyToDataTable();
シンプルにWhereで条件を絞って、条件に合致するDataRowを取得⇒そのDataRowをCopyToDatatableで新たなデータテーブルにコピーってな感じですね!
なんにせよ。このCopyToDatatableというメソッドは結構使えそうですね!
以上!
コメント