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

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

新規登録して質問してみよう
ただいま回答率
85.50%
CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

C#

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

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

2回答

3092閲覧

【C#,Unity】CSVファイルの入力値を読み取る際、列数が最大値に揃えられることで空白値が入力されてしまう

Y0241-N

総合スコア1066

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

C#

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

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2021/05/26 05:29

前提・実現したいこと

Unity内でCSVファイルの読み取りをトライしているのですが、行を読み取る際に列数が最大の列数に揃えられるため、入力していない部分に空白が挿入されてしまいます。
この空白をなんとかして消して空白部分は詰めるようにしたいのですが、自分で試した方法では上手くいきませんでした。

![![イメージ説明

試したこと

ひとまず読み取りの際に列数が揃えられるのは回避できないみたいなので、
読み取った後にTrim()やReplace(" ","")やint.TryParseの際に例外を999に置き換え、その後にListからRemoveするなども試しましたが、削除できませんでした。

cs

1using System; 2using System.Collections; 3using System.Collections.Generic; 4using UnityEngine; 5using System.IO; 6 7public class CSVReadTest : MonoBehaviour 8{ 9 public string FileName; 10 private Dictionary<string,int[]> ReadValue; 11 void Start() 12 { 13 ReadFile(); 14 } 15 16 17 void ReadFile()//読み取った値の保持及び比較、発火を試す 2021年5月25日 18 { 19 20 ReadValue = new Dictionary<string, int[]>(); 21 22 FileInfo filePath = new FileInfo(Application.dataPath + "/" + FileName +".csv"); 23 #if UNITY_EDITOR 24 filePath = new FileInfo(Application.dataPath + "/CSVReader/" + FileName +".csv"); 25 #endif 26 27 if(!filePath.Exists) 28 return; 29 if(filePath.Extension != ".csv") 30 return; 31 32 string path = filePath.ToString(); 33 FileStream fs = new FileStream(path, FileMode.Open,FileAccess.Read, FileShare.ReadWrite); 34 // インスタンスを指定して開く 35 StreamReader sr = new StreamReader(fs); 36 int i = 0; 37 { 38 // 末尾まで繰り返す 39 while (sr.Peek() != -1) 40 { 41 Debug.Log("i" + i); 42 43 // CSVファイルの一行を読み込む 44 string line = sr.ReadLine().Replace(" ",""); 45 // 読み込んだ一行をカンマ毎に分けて配列に格納する 46 string[] values = line.Split(','); 47 48 List<int> flagValues = new List<int>(); 49 50 flagValues.AddRange(Array.ConvertAll(values, s => 51 { 52 int result = 0; 53 if(!int.TryParse(s, out result)) 54 { 55 result = 999; //変換対象が数字に置換できない場合に999をスローする 56 } 57 return result; 58 }) 59 ); 60 61 flagValues.Remove(999); 62 63 foreach(var item in flagValues) 64 { 65 Debug.Log(item);//確認用 66 } 67 i++; 68 } 69 } 70 } 71} 72

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

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

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

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

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

YAmaGNZ

2021/05/26 05:43

例えば A,0,1,2, A,0,,1,2 は空白を無視するようなことになればどちらも同じデータとなります。 省略されている場所に意味はないのでしょうか?
Y0241-N

2021/05/26 05:47

間の空白はこういうケースでも発生するなと思い、追加した次第なのでおっしゃるとおりこの場合は特に意味はありません。 本命は末尾に空白が挿入されてしまい、それを上手く削除できず困っているという部分です。 余計な情報を与えてしまい申し訳ありません。
neconekocat

2021/05/26 06:00

配列から空欄を除きたいってことであってますか? もしそうならWhereにかけてしまうことで解決しそうですが
Y0241-N

2021/05/26 06:05

はい、その認識で合っています。 Linqの使い方はまだまだ未熟なため方法を教えていただけますでしょうか。
YAmaGNZ

2021/05/26 06:25

最初の”A”の部分はどうするんでしょう? 現状だとそれも処理されるような状態ですけど
Y0241-N

2021/05/26 06:29

可能なら1列目は読み飛ばしたいのですが、方法が分からなかったので、とりあえず取得してその後に処理して消せばいいかというのが現状です。 より的確にしたい事を書くと「読み取った行から数字だけを抜き出して保持する」という処理が実装できればと思います。
YAmaGNZ

2021/05/26 06:35

わざわざAとかBとか何かしら区別するような意味のあるデータと思われるものなのに「読み飛ばし」でいいのですか?
Y0241-N

2021/05/26 06:44

先頭の文字は別の部分で使用する目的がありますが、数値を抜き取れればいいと考えていました。 行を読み取ったのちに文字は文字、数値は数値と分けて保持できればありがたいですが、質問投稿時点ではそこまで出来ると思っていなかったので、空白を無視して数字だけ抜き取る方法について質問しました。
guest

回答2

0

ベストアンサー

Linqでやらなくてはいけない理由がないのであれば単純にfor文でループすればいいのでは?

C#

1string line = "A,0, ,2, "; 2 3string[] values = line.Split(','); 4 5List<int> flagValues = new List<int>(); 6 7for(int i = 1 ; i < values.Length ; i++) 8{ 9 int result = 0; 10 if (int.TryParse(values[i], out result)) 11 { 12 flagValues.Add(result); 13 } 14} 15 16string type = values[0]; 17

投稿2021/05/26 06:56

YAmaGNZ

総合スコア10222

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

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

Y0241-N

2021/05/26 07:36

ありがとうございます、確かにint.TryParseで数値かどうかを判定し、数値であれば追加するという方法でよさそうです。
YAmaGNZ

2021/05/26 07:47 編集

もしLinqで行うのであれば int result; flagValues.AddRange(values.Skip(1).SelectMany(s => int.TryParse(s, out result) ? new int[] { result } : new int[0])); といった手もあるかと思います。
guest

0

using Syrtem.Linqを追加してソースの一部をこんな感じにするとかですかね
string[] values = line.Split(',').Where(s => s.Length > 0).ToArray();

投稿2021/05/26 06:20

neconekocat

総合スコア443

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

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

Y0241-N

2021/05/26 07:31

ありがとうございます、こちらの方法とYAmaGNZ様の解答を併用しようと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問