🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Swift

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

Q&A

解決済

1回答

1149閲覧

swift 辞書型 対応する値があれば、順序を保持して出力する方法

anmoanmo

総合スコア2

Swift

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

0グッド

0クリップ

投稿2021/02/04 13:27

編集2021/02/05 18:46

ある問題に挑戦していて、なかなか回答方法が思いつきません。
どうかアドバイスよろしくお願いいたします。

問題
「人」と「人の血液型」、「血液型」と「血液型に対応するラッキーカラー」が入力されるので、それぞれの人に対応するラッキーカラーを表示したいです。

例)
n(入力される数)
(ユーザー_1) (ユーザー_1の血液型)
(ユーザー_2) (ユーザー_2の血液型)
(ユーザー_3) (ユーザー_3の血液型)
m(入力される数)
(血液型_1) (血液型_1のラッキーカラー結果)
(血液型_2) (血液型_2のラッキーカラー結果)
(血液型_3) (血液型_3のラッキーカラー結果)

1から n までの人について順に、その人とそのラッキーカラーを半角スペース区切りで出力したいです。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
3
yuu B
taro O
kai AB
3
B green
O blue
AB yellow

出力
yuu green
taro blue
kai yellow
このような出力結果にしたいです。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
途中経過

swift

1  2let n = Int(readLine()!)! 3var users : [String:String] = [:] 4 5for _ in 0..<n{ 6let tmp = readLine()!.split(separator: " ") 7let user = String(tmp[0]) 8let blood = String(tmp[1]) 9users[user] = blood 10} 11 12let m = Int(readLine()!)! 13var fortunes : [String:String] = [:] 14 15for _ in 0..<m{ 16let tmp = readLine()!.split(separator: " ") 17let blood = String(tmp[0]) 18let fortune = String(tmp[1]) 19fortunes[blood] = fortune 20} 21 22for (user,user_blood) in users{ 23for (blood,fortune) in fortunes{ 24if user_blood == blood{ 25print("(user) (fortune)") 26break 27} 28} 29}

なんとかペアで出力することはできましたが、辞書型なので順番通りに出力ができずに悩んでいます。
KeyValuePairs と定義すれば順番が保持されると分かったのですが、var users : KeyValuePairs = [:]
としてもうまくいきませんでした。

ご回答よろしくお願いいたします。

アドバイスをいただき解決しました。

let n = Int(readLine()!)! var hb = [(String,String)]()//ユーザー名と血液型をタプルで格納する配列 var bf = [(String,String)]()//血液型と占い結果をタプルで格納する配列 for _ in 0..<n{ let tmp = readLine()!.split(separator: " ") let user = String(tmp[0]) let blood = String(tmp[1]) hb.append((user,blood)) } let m = Int(readLine()!)! for _ in 0..<m{ let tmp = readLine()!.split(separator: " ") let blood = String(tmp[0]) let fortune = String(tmp[1]) bf.append((blood,fortune)) } for i in hb{ for ii in bf{ if i.1 == ii.0{ print("(i.0) (ii.1)") } } }

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

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

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

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

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

hoshi-takanori

2021/02/04 19:14

これだと単なる丸投げなので、ご自分でできるところまでプログラムを書いてみませんか? まったく何も書けないのであれば、もっと最初の方から勉強をし直す必要があると思います。
anmoanmo

2021/02/04 23:13

わかりました
hoshi-takanori

2021/02/05 07:43

そこまで出来たらもう一息ですね。KeyValuePairs ではなく、タプルの配列を使うと良いでしょう。 また、質問文中にコードを貼る場合は <code> 機能を使ってインデントされた状態にしてもらえると助かります。 https://apuridasuo.hatenablog.com/entry/2019/10/20/220308#%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E8%B2%BC%E3%82%8B%E3%81%A8%E3%81%8D%E3%81%AF%E3%82%BF%E3%82%B0%E3%81%A7%E5%9B%B2%E3%82%80
anmoanmo

2021/02/05 15:49

ありがとうございます。 編集して直します。 タプルの配列ですね。いい方法が思いつかず苦戦しているので、でき次第再投稿します。 もしお時間があれば、またアドバイスよろしくお願いいたします。
guest

回答1

0

ベストアンサー

辞書型だと順番が保存されないので、代わりにタプルの配列を使うと良いでしょう。

まず、タプルとは、いくつかの値の組み合わせです。配列は同じ型の値を複数 (数は増減可能) 持つことができますが、タプルは異なる型 (同じ型でもいいけど) の値を決まった数だけ持つことができます。また、配列は [] で囲みますが、タプルは () で囲んで書きます。

swuift

1let tuple1 = (123, "abc", true) // 型は (Int, String, Bool) 2let tuple2 = ("yuu", "B") // 型は (String, String)

次に、タプルの配列ですが、タプルも型なので、配列にすることができます。

swift

1let tuples = [ // 型は [(String, Int)]、つまり (String, Int) という型のタプルの配列 2 ("yuu", 123), 3 ("taro", 456), 4 ("kai", 789), 5]

今回は、users を (String, String) 型のタプルの配列にすると良いでしょう。

swift

1var users: [(String, String)] = []

users に値を追加するには append メソッドを使います。

swift

1let tuple = (user, blood) 2users.append(tuple) 3 4// または、次のようにも書けます。括弧 () が二重になることに注意。 5// 外側の括弧は append の引数を囲むもので、内側の括弧はタプルを表します。 6users.append((user, blood))

タプルの値にアクセスすには、.0 や .1 などを使います。

let tuple = ("yuu", "B") print(tuple.0) // yuu と表示される。 print(tuple.1) // B と表示される。

または、分割代入もできます。

let tuple = ("yuu", "B") let (user, blood) = tuple print(user) // yuu と表示される。 print(blood) // B と表示される。

タプルの値をすべて表示する方法はこんな感じです。

let users = [ ("yuu", "B"), ("taro", "O"), ("kai", "AB"), ] // 方法その 1 - タプルをまるごと変数 tuple で受け取る。 for tuple in users { print("(tuple.0) (tuple.1)") } // 方法その 2 - タプルを user, blood にばらして受け取る。 for (user, blood) in users { print("(user) (blood)") }

最後の表示の部分ですが、fortunes は辞書なので、ループしなくても、fortunes[血液型] で直接目的の血液型のラッキーカラーにアクセスできます。ただし、結果はオプショナル (String? 型、指定した血液型が存在しない場合は nil になる) ので、if let を使うと良いでしょう。

swift

1for (user, blood) in users { 2 if let fortune = fortunes[blood] { 3 print("(user) (fortune)") 4 } 5}

投稿2021/02/05 16:52

hoshi-takanori

総合スコア7899

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

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

anmoanmo

2021/02/05 18:42

最後まで丁寧に教えていただき本当にありがとうございます。 なんとか完成させることができました。 諦めずにやってよかったです。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問