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

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

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

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

2回答

473閲覧

structの各要素に順番に配列の要素を入れていくやり方はありませんか?

KTH

総合スコア86

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2020/07/07 10:20

swift

1struct food { 2 var Group,FoodNumber,ListNumber,Tagnames,REFUSE,ENERC_KCAL,ENERC,WATER,PROTAIN,PROTCAA,FAT,FATNLEA,FASAT,FAMS,FAPU,CHOLE,CARBON,CHOAVLM,FIBSOL,FIBINS, FIBTG,ASH,NA,K,CA,MG,P,FE,ZN,CU,MN,ID,SE,CR,MO,RETOL,CARTA ,CARTB ,CRYPXB,CARTBEQ,VITA_RAE,VITD,TOCPHA,TOCPHB ,TOCPHG,TOCPHD,VITK,THIAHCL ,RIBF,NIA,VITB6A,VITB12,FOL,PANTAC,BIOT,VITC,NACL_EQ,ALC,NITRA ,THEBRN,CAFFN ,TAN,POLYPHENT,ACEAC,OIL,OA,CHANGEOFWAIT:String 3}

こういうStructがあるときに

swift

1["01", "01001", "1", "アマランサス 玄穀 ", "0", "358", "1498", "13.5", "12.7", "(12.5)", "6.0", "5.0", "1.18", "1.48", "2.10", "(0)", "64.9", "63.5", "1.1", "6.3", "7.4", "2.9", "1", "600", "160", "270", "540", "9.4", "5.8", "0.92", "6.14", "1", "13", "7", "59", "(0)", "0", "2", "0", "2", "Tr", "(0)", "1.3", "2.3", "0.2", "0.7", "(0)", "0.04", "0.14", "1.0", "0.58", "(0)", "130", "1.69", "16.3", "(0)", "0", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-"]

こういう配列があるとして、配列の中の要素をstructに順番に入れていくうまいやり方は有りませんか?

Structの各要素にうまく配列を入れる方法がわかる方がいればよろしければ教えてください

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

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

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

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

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

fuzzball

2020/07/07 11:34

「うまいやり方」とか「うまく配列を入れる方法」を具体的に書いてください。
KTH

2020/07/07 12:12

それを知ってたら自分でやるから質問しないでしょwww
fuzzball

2020/07/07 12:33

何をもって「うまい」のか定義しろと言っているのですがね。
guest

回答2

0

そのフィールドの数を見ると、一つ一つに値を入れたくないな〜って思ってしまいますね。残念ながら、structを用いる限り一つ一つに入れるしかありません。

けど、Dictionaryを用いたら便利な書き方があります。まずは、その長いフィールド行をコピーして配列を作ります。

swift

1let keys = ["Group","FoodNumber","ListNumber","Tagnames","REFUSE","ENERC_KCAL","ENERC","WATER","PROTAIN","PROTCAA","FAT","FATNLEA","FASAT","FAMS","FAPU","CHOLE","CARBON","CHOAVLM","FIBSOL","FIBINS","FIBTG","ASH","NA","K","CA","MG","P","FE","ZN","CU","MN","ID","SE","CR","MO","RETOL","CARTA","CARTB","CRYPXB","CARTBEQ","VITA_RAE","VITD","TOCPHA","TOCPHB","TOCPHG","TOCPHD","VITK","THIAHCL","RIBF","NIA","VITB6A","VITB12","FOL","PANTAC","BIOT","VITC","NACL_EQ","ALC","NITRA ","THEBRN","CAFFN ","TAN","POLYPHENT","ACEAC","OIL","OA","CHANGEOFWAIT"]

配列にするのは、前後に[""]をつけて、その1行だけにコンマ,を検索して","で書き換えます。空白がいくつかありますが削除していいです。

そうしたら、問題文の値の配列をvaluesで名付けて:

swift

1let values = ["01", "01001", "1", "アマランサス 玄穀 ", "0", "358", "1498", "13.5", "12.7", "(12.5)", "6.0", "5.0", "1.18", "1.48", "2.10", "(0)", "64.9", "63.5", "1.1", "6.3", "7.4", "2.9", "1", "600", "160", "270", "540", "9.4", "5.8", "0.92", "6.14", "1", "13", "7", "59", "(0)", "0", "2", "0", "2", "Tr", "(0)", "1.3", "2.3", "0.2", "0.7", "(0)", "0.04", "0.14", "1.0", "0.58", "(0)", "130", "1.69", "16.3", "(0)", "0", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-"]

そしてkeysvaluesで簡単にDictionaryを作れます!

swift

1let food = Dictionary(uniqueKeysWithValues: zip(keys, values))

どうしてもstructを使わなければいけない場合は、コードを生成しましょう!REPL でコードを生成してコピーし、ソースにペーストしたいと思います。fuzzballさんのコードをテンプレートにして

swift

1struct Food { 2 var Group,FoodNumber,ListNumber,Tagnames,REFUSE,ENERC_KCAL,ENERC,WATER,PROTAIN,PROTCAA,FAT,FATNLEA,FASAT,FAMS,FAPU,CHOLE,CARBON,CHOAVLM,FIBSOL,FIBINS, FIBTG,ASH,NA,K,CA,MG,P,FE,ZN,CU,MN,ID,SE,CR,MO,RETOL,CARTA ,CARTB ,CRYPXB,CARTBEQ,VITA_RAE,VITD,TOCPHA,TOCPHB ,TOCPHG,TOCPHD,VITK,THIAHCL ,RIBF,NIA,VITB6A,VITB12,FOL,PANTAC,BIOT,VITC,NACL_EQ,ALC,NITRA ,THEBRN,CAFFN ,TAN,POLYPHENT,ACEAC,OIL,OA,CHANGEOFWAIT:String 3 init(withValues values: [String]) { 4 // 中身 5 // self.フィールド名 = values[i] 6 } 7}

まずはフィールド列を文字列にします:

swift

1var fieldList = "Group,FoodNumber,ListNumber,Tagnames,REFUSE,ENERC_KCAL,ENERC,WATER,PROTAIN,PROTCAA,FAT,FATNLEA,FASAT,FAMS,FAPU,CHOLE,CARBON,CHOAVLM,FIBSOL,FIBINS, FIBTG,ASH,NA,K,CA,MG,P,FE,ZN,CU,MN,ID,SE,CR,MO,RETOL,CARTA ,CARTB ,CRYPXB,CARTBEQ,VITA_RAE,VITD,TOCPHA,TOCPHB ,TOCPHG,TOCPHD,VITK,THIAHCL ,RIBF,NIA,VITB6A,VITB12,FOL,PANTAC,BIOT,VITC,NACL_EQ,ALC,NITRA ,THEBRN,CAFFN ,TAN,POLYPHENT,ACEAC,OIL,OA,CHANGEOFWAIT"

空白を抜きおいて:

swift

1fieldList.removeAll(where: { $0.isWhitespace })

フィールド名配列をsplitで作ります:

swift

1let fieldNames = fieldList.split(separator: ",")

そうしたら、init(withValues: [String])の中身を生成します:

swift

1for (index, name) in fieldNames.enumerated() { 2 print("self.(name) = values[(index)]") 3}

結果は下記の通りです。是非お試してみてください。

swift

1self.Group = values[0] 2self.FoodNumber = values[1] 3self.ListNumber = values[2] 4self.Tagnames = values[3] 5self.REFUSE = values[4] 6self.ENERC_KCAL = values[5] 7self.ENERC = values[6] 8self.WATER = values[7] 9self.PROTAIN = values[8] 10self.PROTCAA = values[9] 11self.FAT = values[10] 12self.FATNLEA = values[11] 13self.FASAT = values[12] 14self.FAMS = values[13] 15self.FAPU = values[14] 16self.CHOLE = values[15] 17self.CARBON = values[16] 18self.CHOAVLM = values[17] 19self.FIBSOL = values[18] 20self.FIBINS = values[19] 21self.FIBTG = values[20] 22self.ASH = values[21] 23self.NA = values[22] 24self.K = values[23] 25self.CA = values[24] 26self.MG = values[25] 27self.P = values[26] 28self.FE = values[27] 29self.ZN = values[28] 30self.CU = values[29] 31self.MN = values[30] 32self.ID = values[31] 33self.SE = values[32] 34self.CR = values[33] 35self.MO = values[34] 36self.RETOL = values[35] 37self.CARTA = values[36] 38self.CARTB = values[37] 39self.CRYPXB = values[38] 40self.CARTBEQ = values[39] 41self.VITA_RAE = values[40] 42self.VITD = values[41] 43self.TOCPHA = values[42] 44self.TOCPHB = values[43] 45self.TOCPHG = values[44] 46self.TOCPHD = values[45] 47self.VITK = values[46] 48self.THIAHCL = values[47] 49self.RIBF = values[48] 50self.NIA = values[49] 51self.VITB6A = values[50] 52self.VITB12 = values[51] 53self.FOL = values[52] 54self.PANTAC = values[53] 55self.BIOT = values[54] 56self.VITC = values[55] 57self.NACL_EQ = values[56] 58self.ALC = values[57] 59self.NITRA = values[58] 60self.THEBRN = values[59] 61self.CAFFN = values[60] 62self.TAN = values[61] 63self.POLYPHENT = values[62] 64self.ACEAC = values[63] 65self.OIL = values[64] 66self.OA = values[65] 67self.CHANGEOFWAIT = values[66]

追記:fuzzballさんがリフレクションの使い方を教えてくれました!ありがとうございます!

swift

1struct Food { var Group, FoodNumber, (中略) : String? } //一時的にオプショナル型にする 2 3Mirror(reflecting: Food()).children.compactMap { $0.label }.enumerated().forEach { 4 print("self.($0.element) = values[($0.offset)]") 5}

struct Foodの中のvarの型が元はStringですが、Food()を使えるようになるため、String?みたいに?で後飾ってオプショナル型にします。

compactMapforEachが実にいいことで覚えるのをおすすめですが、for loopで書いたらこうなります:

swift

1for (offset, (label, _)) Mirror(reflecting: Food()).children.enumerated() { 2 print("self.(label) = values[(offset)]") 3}

出力は上記と同じになります。

投稿2020/07/07 22:41

編集2020/07/10 02:07
YufanLou

総合スコア464

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

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

fuzzball

2020/07/10 00:41

リフレクションを使うと、わざわざテーブルを作らなくても名前を取り出せます。 struct Food { var Group, FoodNumber, (中略) : String? } //一時的にオプショナル型にする Mirror(reflecting: Food()).children.compactMap { $0.label }.enumerated().forEach { print("self.($0.element) = values[($0.offset)]") }
YufanLou

2020/07/10 01:39

リフレクションを使おうとしましたけどinitに値を入れなければならなかったのでやめました。なるほど、オプショナル型にすればデフォルトinitで空でも大丈夫ですね!勉強になりました!
guest

0

普通に

swift

1let values = ["01", "01001", "1", "アマランサス 玄穀 "] 2struct Food { 3 var group, foodNumber, listNumber, tagnames: String 4} 5let food = Food(group: values[0], foodNumber: values[1], listNumber: values[2], tagnames: values[3]) 6print("group:", food.group) 7print("foodNumber:", food.foodNumber) 8print("listNumber:", food.listNumber) 9print("tagnames:", food.tagnames) 10//group: 01 11//foodNumber: 01001 12//listNumber: 1 13//tagnames: アマランサス 玄穀 

初期化をシンプルに

swift

1let values = ["01", "01001", "1", "アマランサス 玄穀 "] 2struct Food { 3 var group, foodNumber, listNumber, tagnames: String 4 init(_ values: [String]) { 5 group = values[0] 6 foodNumber = values[1] 7 listNumber = values[2] 8 tagnames = values[3] 9 } 10} 11let food = Food(values) //simple! 12print("group:", food.group) 13print("foodNumber:", food.foodNumber) 14print("listNumber:", food.listNumber) 15print("tagnames:", food.tagnames) 16//group: 01 17//foodNumber: 01001 18//listNumber: 1 19//tagnames: アマランサス 玄穀 

投稿2020/07/07 12:05

編集2020/07/07 14:15
fuzzball

総合スコア16733

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

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

fuzzball

2020/07/07 14:16 編集

(修正済)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問