質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

3回答

7197閲覧

c#でのcsvファイル読み込み、数値2次元配列化

退会済みユーザー

退会済みユーザー

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

1クリップ

投稿2017/10/25 10:55

###前提・実現したいこと
c#でcsvファイルを読み込み数値の2次元配列として扱いたいです。
以降のプログラムでもその配列の列を操作等するのでオブジェクトとして読みこみたいです。
csvファイルはスペース区切りで数字が500行程度6列並んでいます。
ヘッダがあるので、飛ばしてかつ、稀に数字前後に区切りスペースとは別にスペースがあるので
それも除去したいです。
pythonではpandasを使って上記のことをしていたのですが、c#は勉強して間もないです。
ソースコードを一から書いていただくの失礼ですし、自分のためにもならないので、
方法やキーワードを示唆していただくと助かります。
至らない点ありますが、ご教授願います。

###発生している問題・エラーメッセージ

エラーメッセージ

###該当のソースコード
質問自体が初歩的なので、ソースコードは載せてもあまり意味がないので載せてません。

###試したこと
ネットや書籍で調べていろいろ試しました。
まず最初にStreamReaderを使って、読みこむこと自体はできました。
ただ文字列としてしか読み込めない、pythonでいうinitialspaceが除去できない等問題がありました。
つぎにlinqを使って試しましたが、ヘッダを飛ばせないことや、以降のプログラムで数値二次元配列
として扱う方法がわからないこと等で止まってしまいました。
他にもTextFieldParserを使う方法、DataTableを使う方法を検討しました。

###補足情報(言語/FW/ツール等のバージョンなど)
Visual Studio Community使用

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

スマートな方法はわからないので、回りくどいかもしれませんが自分ならこうする、という方法になります。

・まずはcsvをList<string> listに読み込む。ただし1行目はヘッダなので無視。
・値を保持する配列としてary[list.Count, 6]を作成する。
・listの各行(string)に対し以下を行う。
・string[] buf = list[i].Split(' ')をする。
・buf[]から値が""でないもの(6個のはず)を抜き出してary[,]に入れる

余談ですが、私はC#しか経験がなく、先月よりpythonを始めましたがご質問を読む限りpythonだとこういうことが簡単にできそうに感じ、驚きです。

投稿2017/10/25 12:24

Takamu2445

総合スコア13

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/10/25 12:53

回答ありがとうございます。とても参考になります。 説明いただいたように書いてみたいと思います。 こちらも余談になりますがpythonではコードが読みやすく、すっきりしていると思います。 c#はなかなか手ごわいです。上達に向けて頑張りたいと思います。
guest

0

ベストアンサー

どのような環境で開発を行っているかにも寄りますが,.NET Frameworkで開発(Windows向け)するのであれば,TextFieldParserとDataTableを使うのが最も簡単ではないかと思います.

.NET CoreやXamarinなど,より汎用的に使える手法で読み込みたいのであれば,StreamReaderをつかってReadLineするときに,Split関数を使うのが良いのではないでしょうか.
具体的には以下のようになるかと思います.

sr.ReadLine().Split(' ');
sr.ReadLine().Split(new char[]{' '}, StringSplitOptions.RemoveEmptyEntries);

上の場合では,単純に空白で分割します.この場合,空白が連続していると空文字もひとつの文字列として配列化されてしまうので,その場合は下の方を使います.

ヘッダを飛ばしたいのであれば,ReadLine()をしてそのまま何も処理せずに再度ReadLine()を呼び出せば1行目は何もせずに飛ばすのはどうでしょうか?

読み出した物を数値にパースする場合は,
Int32.Parse()やSingle.Parse()等を用いて,以下のようにするのが良いのではないでしょうか.
しかし,この場合パースできない文字列が来た場合は例外が吐かれるので,代わりにTryParse()等を用いる方法があります.

また,蛇足ですが,二次元配列は扱いが少々面倒なので,データを操作する都合上問題ないのであれば,ジェネリックコレクション等使う方が良いのではないでしょうか.

投稿2017/10/25 11:38

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/10/25 12:31

回答ありがとうございます。 ケースに分けて、対処できるように説明いただいたのでとてもわかりやすかったです。 c#は勉強始めたばかりなので、説明が詳しくて今後の参考になります。 まだまだ知識不足なので、いろいろな書き方を身に着けていきたいです。 重ねて感謝申し上げます。
退会済みユーザー

退会済みユーザー

2017/10/25 12:45

回答に補足説明です. 編集でつじつまが合わなくなってたのですが,パースの所,以下のようにと例示していたのですが,あまり答えを書かないようにとのことで削除しておりました. 参考までに以下のように書きますとだけ. var hoge = sr.ReadLine().Split(' '); var piyo = hoge.Select(n => Int32.Parse(n)).ToArray();
退会済みユーザー

退会済みユーザー

2017/10/25 12:58

補足説明ありがとうございます。参考にさせていただきます。
guest

0

List<int[]> list = new List<int[]>(); foreach(var line in System.IO.File.ReadLines(path).Skip(1)) { list.Add(line.Split(',').Select(n=> int.TryParse(n.Trim(), out int result) ? result : 0 ).ToArray()); }

こんな感じか。キーワードしかない。基本LINQを使った処理で、三項演算子を使っているという感じか。
ちょっと、C#7.0から使えるのを使っているので、古いのだと動かないかな。
テキストファイルを読むなら、System.IO.File.ReadLinesが大正義。
DataTableは過去の遺物なのでつかってはいけない。

投稿2017/10/25 11:26

編集2017/10/25 12:09
kiichi54321

総合スコア1984

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/10/25 12:36

回答ありがとうございます。 具体的なコードも明示していただいて、とても参考になります。 c#から始めてcの歴史も知らないので何が今便利なのか、そのあたりも今後勉強していきたいです。 このように自分もすぐにコードが書けるように精進したいです。 重ねて感謝申し上げます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問