見出し画像

【じっくりSw1ftUI 28】Essentials第14章〜Playgroundで遊ぼう14〜配列と辞書 (ディクショナリ)②辞書 キーを使って、整理しやすくできるってイメージ🕺

さてと、前回

配列をやったので〜〜〜最後にも書いたとおり、今回は、

辞書(ディクショナリ)

を楽しくじっくりやってく〜〜〜〜🕺ま、

VBAとかRPAでも

辞書=高速化

って感じでやりたがる人は多いんだけど、そーゆー人ほど、

辞書は重複を許さないエラー

なんかを考慮せずに、バカのひとつ覚えみたいに組んで、要求が、

重複する運用もあり得る

みたいに変わった瞬間に、

大幅に書き換えが発生して涙目😢

なんてことになって、

教科書通りにしか組むことができない=対応できない
自称VBAエンジニアさんほど、最終的には、

で書いた、普段は組織内で

  1. 空気みたいに存在感がない

  2. 影が薄い

  3. 自分たちが理解ができないくらいあっさりしたコードしか書かないから素人と勝手に評価して見下してる

  4. 仕事が出来ないと毛嫌いしてる

👉ジョーカーやラストエンジニア

に頼ってきたりするからね藁🤣

そんな恥ずかしい=他の職場で仕事がないようなエンジニアにはならないように気をつけようね〜〜〜〜

例えば、VBAで高速化するだけであれば、

  • 高速するコードを組み込む

  • selectではなく、activateを使う

なんかをやるだけで処理速度は格段に上がるんだけど、、、。

ま、実はその手法の一端は、年末に書いた

でしれっと紹介はしてるんだけね💦👀

最近のIT業界は海外では30年以上前からやってる

リファクタリング

って手法を数年前から取り入れ始めて、猫も杓子もバカの一つ覚えみたいになんでも小分けにすればいいと思ってるからね🧐
リファクタリングは実は、下手に細分化し過ぎると、

呼び出しや引数の多さなんかから極端に処理速度が落ちる=諸刃の剣

だから、

コードチューニング

を知らない人はやらない方がいい手法なんだけど、

みたいな本が、爆発的にヒットしたからなのか、世界的なバイブル書である、

を読んでないのか知らないけど、小分けにしすぎて、自分たちで

  • コードの読みやすさ(可読性)を低くする

  • 処理時間を増やす

ってことをやり続けてるからね〜〜〜

👉リファクタリングとコードチューニングはセットで理解する

を忘れないようにね🕺

で過去に感想文で書いてるから、興味がある人は参考にしてみてね。

リファクタリングって要は、

既存のコードを安全に管理する手法

なだけで、

再利用するモジュールを
何でもかんでも小分けにすればいいって手法ではない

からね。

さてと、ではそろそろ本題に〜〜〜

ま、今回もオイラの学びなんて要らないって人は、

で、今からやる本の内容も丸々公開されてるみたいだから、勝手にみてね〜〜〜

じっくり第14章の辞書(ディクショナリ)以降を読んでく

まずは、辞書について

格納する値をキーと値のペアで管理する手法
👉やりたい目的は、配列と一緒

って言ってんね👀

ここでポイント①

ユニークなキーで補完していて、キーには、以下の型しかできないみたいね

  1. String

  2. Int

  3. Double

  4. Bool

ま、やったことがある人間からしたら、

「そりゃそーだし、それだけありゃ十分だろ」

って感じなんだけど、やったことがない人にはイメージが湧かないだろうから

構文

var varidableDictionary: [key Type: value Type] = [key1: value1, key2: value2, ... ]

八百屋さんの商品リストをイメージして実際に動かしてみる🕺

var yaoya14_13:[Int: String] = [1:"🍏",2:"🍌",3:"🍇",4:"🍓",5:"🍈",6:"🍍",7:"🍋",8:"🍉"]

てなコードで🍌を呼び出してみる〜〜〜

print(yaoya14_13[2])

で実行すると、

Optional型になってんね💦

なので、

print(yaoya14_13[2]!)

で強制アンラップして〜〜〜

ホイ、🍌がちゃんと出てきた〜〜〜〜

キーと値の配列をガッチャンこもできる

//キーと値を分けた配列を結合
var yaoyaKeys14_14 = [1,2,3,4,5,6,7,8]
var yaoyaValues14_14 =
["🍏","🍌","🍇","🍓","🍈","🍍","🍋","🍉"]
var yaoya14_14 = Dictionary(uniqueKeysWithValues: zip(yaoyaKeys14_14, yaoyaValues14_14))
print(yaoya14_14)

てな感じで実行すると〜〜〜

ガッチャンこはできたけども順番が藁🤣
本の実行結果になってないんですけども笑

そこで.sortedメソッドなんかを使って〜〜〜

print(yaoya14_14.sorted(by: <))

てな感じで実行して、

てな感じで並び替えもできなくはないんだけど、、、

要は、値の配列に1から順に番号を振れればいいだけ

だから

//1から順に番号を振るだけ
var yaoya14_15 = Dictionary(uniqueKeysWithValues: zip(1..., yaoyaValues14_14))
print(yaoya14_15)
てな感じでも番号は触れるみたいだけど、どっちにしても順番が〜〜〜笑💦

なので

なんかを参考に、

var sortedYaoya14_16 = yaoya14_15.sorted{$0.key < $1.key }
print(sortedYaoya14_16)

でやってもこれだけだと

順番は整列できたけど、なんか違う 藁🤣

さらに、

なんかを参考にして〜〜〜

var sortedYaoya14_16 = yaoya14_15.sorted{$0.key < $1.key }
print(sortedYaoya14_16)
for element in sortedYaoya14_16 {
    print("\(element.key):\(element.value)")
}

で実行してみると、、、

てな感じになるのね。。。💦

と、ここまでで沼りそうなので、先に進む〜〜〜

辞書項目の数を数える

//個数
print("項目数は、\(sortedYaoya14_16.count)だぜ!")
でけた〜〜〜

辞書の項目を呼び出し

//キーが3の値を呼び出し
print(yaoya14_13[3]!)
ここは最初にやった感じで〜〜〜

存在しないキーにアクセスしてみると、、、

//存在しないキーにアクセスしてみると、、、
print(yaoya14_13[9,default:"木梨(キーなし)さん"])
てな感じになる👀

🍑ちゃんを逆に9キーを作って追加してみる

//🍑ちゃんを逆に9キーを作って追加してみる
yaoya14_13[9] = "🍑"
print(yaoya14_13[9,default:"木梨(キーなし)さん"])
print(yaoya14_13)
ちゃんと9: "🍑"が追加された〜〜〜

さっき追加した🍑ちゃんを🍐先輩に変更してみる

//🍑から🍐へ
yaoya14_13.updateValue("🍐", forKey: 9)
print(yaoya14_13[9,default:"木梨(キーなし)さん"])
print(yaoya14_13)
ちゃんと🍑ちゃんから🍐先輩に変わってるね👀

🍐先輩のみを削除してみる

//🍐を値のみ削除
yaoya14_13[9] = ""
print(yaoya14_13[9,default:"木梨(キーなし)さん"])
print(yaoya14_13)
値のみ空欄に、、、

🍐先輩がどこかに行ったので、キーも削除

//値が空欄判定を行い、空欄の場合はキーごと削除
if yaoya14_13[9] == "" {
    yaoya14_13[9] = nil
    print(yaoya14_13[9,default:"木梨(キーなし)さん"])
    print(yaoya14_13)
}
ホイ、削除でけた〜〜〜

他のメソッドで削除も出来るみたいなので〜〜〜

//7キーを削除
yaoya14_13.removeValue(forKey: 7)
print(yaoya14_13)
消えた〜〜〜

最後に繰り返しを使ってお遊び

//キーと値を使って商品番号と商品名を表示
for (key,value) in yaoya14_13 {
    print("商品番号\(key)は、\(value)です")
}
ハイ、できた〜〜〜〜
//ソートしたヤツで試すと、、、
for (key,value) in sortedYaoya14_16 {
    print("商品番号\(key)は、\(value)です")
}
綺麗に並んで取り出しが出来るってゆーね

本の流れでは以上🕺

今回のまとめコード

前回分とまとめて今回は表示しとくね〜〜〜

/**:-------------------
 Essentials 第14章 配列
 ---------------------*/
//型指定なし
var fruitsBaskets14_1 = ["🍏","🍌","🍇","🍓"]
//型指定あり
var fruitsBaskets14_2:[String] = ["🍈","🍍","🍋","🍉"]
//インスタンス
var fruitsBaskets14_3 = [String]()
var fruitsPrices14_4 = [Float]()
//インスタンスに初期値を設定
var fruitsBaskets14_5 = [String](repeating: "りんご", count: 3)
//実行
print(fruitsBaskets14_5.count)
//配列を結合
var fruitBaskets14_6 = fruitsBaskets14_1 + fruitsBaskets14_2
//実行
print(fruitBaskets14_6.self)
//条件分岐
if fruitsBaskets14_3.isEmpty {
    print("値が何もないぞ👀")
} else {
    print("値があるぞ👀")
}
//りんごにアクセス
print(fruitsBaskets14_1[0])
//バナナにアクセス
print(fruitsBaskets14_1[1])
//シャッフル
let shuffledFruitsBaskets14_7 = fruitBaskets14_6.shuffled()
print(shuffledFruitsBaskets14_7.self)
//ランダム
let randomFruitsBaskets14_8 = shuffledFruitsBaskets14_7.randomElement()
print(randomFruitsBaskets14_8!.self)//強制アンラップして〜〜
//要素に桃を追加
fruitsBaskets14_2 += ["🍑"]
//実行
print(fruitsBaskets14_2.self)
//結合のやつをまんま実行
print(fruitBaskets14_6.self)
//結合し直してあげる
var combinedFruits14_9 = fruitsBaskets14_1 + fruitsBaskets14_2
print(combinedFruits14_9.self)
//りんごとバナナの間にもう一個🍑入れてみよう
combinedFruits14_9.insert("🍑", at: 1)
print(combinedFruits14_9)
//最後の🍑を削除
combinedFruits14_9.removeLast()
print(combinedFruits14_9)
//さっきの🍑も削除
combinedFruits14_9.remove(at: 1)
print(combinedFruits14_9)
//反復
for fruits in combinedFruits14_9 {
    print(fruits)
}
//いったん全要素を削除
combinedFruits14_9.removeAll()
print(combinedFruits14_9)
//8個の要素を追加
for n in 0...8 {
    combinedFruits14_9.insert("🍑", at: 0)
}
print(combinedFruits14_9.self)
//いったん全要素を削除
combinedFruits14_9.removeAll()
//元に戻す
combinedFruits14_9 = fruitsBaskets14_1 + fruitsBaskets14_2
print(combinedFruits14_9)
//キーワードを使って
combinedFruits14_9.forEach{
    print($0)
}
//八百屋
var yaoya14_10:[Any] = ["🍏",123]
var yaoya14_11:[Any] = ["🍏",123,"🍌",200]
var yaoya14_12:[Any] = ["🍏","🍌",123,200]
//繰り返しで出力
yaoya14_12.forEach{
    print($0)
}
for item in yaoya14_12 {
    print(item)
}
//キャスト〜〜〜
//for item in yaoya14_12 {
//    print(item as!Int * 100)
//}
/**:-------------------
 Essentials 第14章 辞書
 ---------------------*/
var yaoya14_13:[Int: String] = [1:"🍏",2:"🍌",3:"🍇",4:"🍓",5:"🍈",6:"🍍",7:"🍋",8:"🍉"]
print(yaoya14_13[2]!)
//キーと値を分けた配列を結合
var yaoyaKeys14_14 = [1,2,3,4,5,6,7,8]
var yaoyaValues14_14 =
["🍏","🍌","🍇","🍓","🍈","🍍","🍋","🍉"]
var yaoya14_14 = Dictionary(uniqueKeysWithValues: zip(yaoyaKeys14_14, yaoyaValues14_14))
print(yaoya14_14)
print(yaoya14_14.sorted(by: <))
//1から順に番号を振るだけ
var yaoya14_15 = Dictionary(uniqueKeysWithValues: zip(1..., yaoyaValues14_14))
print(yaoya14_15)
var sortedYaoya14_16 = yaoya14_15.sorted{$0.key < $1.key }
print(sortedYaoya14_16)
for element in sortedYaoya14_16 {
    print("\(element.key):\(element.value)")
}
//個数
print("項目数は、\(sortedYaoya14_16.count)だぜ!")
//キーが3の値を呼び出し
print(yaoya14_13[3]!)
//存在しないキーにアクセスしてみると、、、
print(yaoya14_13[9,default:"木梨(キーなし)さん"])
//🍑ちゃんを逆に9キーを作って追加してみる
yaoya14_13[9] = "🍑"
print(yaoya14_13[9,default:"木梨(キーなし)さん"])
print(yaoya14_13)
//🍑から🍐へ
yaoya14_13.updateValue("🍐", forKey: 9)
print(yaoya14_13[9,default:"木梨(キーなし)さん"])
print(yaoya14_13)
//🍐を値のみ削除
yaoya14_13[9] = ""
print(yaoya14_13[9,default:"木梨(キーなし)さん"])
print(yaoya14_13)
//値が空欄判定を行い、空欄の場合はキーごと削除
if yaoya14_13[9] == "" {
    yaoya14_13[9] = nil
    print(yaoya14_13[9,default:"木梨(キーなし)さん"])
    print(yaoya14_13)
}
//7キーを削除
yaoya14_13.removeValue(forKey: 7)
print(yaoya14_13)
//キーと値を使って商品番号と商品名を表示
for (key,value) in yaoya14_13 {
    print("商品番号\(key)は、\(value)です")
}
//ソートしたヤツで試すと、、、
for (key,value) in sortedYaoya14_16 {
    print("商品番号\(key)は、\(value)です")
}

Apple公式

さてと、次回は

プログラミングをやってく上では欠かせない

  • 熟練者とか慣れた人だと大好き

  • 慣れていない人は大嫌い

なエラーについて扱った

第15章 エラーハンドリング

をやってく〜〜〜🕺

WEBなんかの記事を見てると、

テスト系で作業をしてるだけなのに、自分がコードを書いた後で、エラーが出るのを嫌がる

エラー拒否症候群

みたいな人もいるみたいだけど、別に開発中なんてエラーなんて起こして当たり前だし、そのためにSwiftは、

静的プログラミング言語
PlaygroundやXcodeでエラーなコード書いた瞬間に警告を出してくれる作りになってる
👉Swiftの最大の旨みのひとつ

なんだから、

エラーなんて正しく付き合えば大丈夫

だし、

そんなもんを使わずに、1回で完璧コードを書けるのが職人

みたいなことなんて全然考えなくて大丈夫🕺
そんな勝手な職人像=素人考えはさっさとドブに捨てて、
むしろ、最初のうちは、たくさんエラーを出して、エラーを出す度に、

なんでこのエラーは出てるんだろう

って考えるのが、

遠回りなようで、上達の近道

どのプログラミング言語でもそうだけどね。

エラーとうまく付き合えれば、百戦危うからず

ってヤツです。

なので、これまでのシンタックス編

で、オイラがバラまいてるサンプルコードなんかを使って、適当に1文字消して、

どんなエラーが出てくるか

で遊んでみるのもひとつ🕺

最初からエラーも出さずにどのコードも完璧に書けるなんて

ごく一部の天才しかいないし、そもそも、

完璧なコードって何ですか?(何それ、美味しいの👀?)

って話だし、あくまでも、自分の作りたいアプリを作れればいいだけで、そんな

完璧なコードを書かないといけない、テスト段階からエラーを出してはいけないみたいな競技をしてるわけじゃないからね。

👉そんなもん目指さなくていい

てか目指したところで、

「エラーを出さずにどのコードも書けるようになりました。しかし、簡単なアプリすら作れません。」

だと、意味ないからね。

何のために、Swiftを学び始めたのかを忘れないように〜〜〜
ま、いくらゆーてもそんな人多いんだけどね💦
特に、自分ではコードを書かない人=素人がゆーてるだけだから。

じゃまた次回〜〜〜🕺
みなさんも良き3連休を〜〜〜

記事公開後

を参考に今回も〜〜〜

てな
てな
感じで、ハイ出来上がり〜〜〜

コード

◆Essentials14_2.swift

import SwiftUI
import WebKit

struct Essentials14_2: View {
    var body: some View {
        VStack{
            TabView {
                Essentials14_2Code()
                    .tabItem {
                        Image(systemName: codeImageTab)
                        Text(codeTextTab)
                    }
                Essentials14_2Points()
                    .tabItem {
                        Image(systemName: pointImageTab)
                        Text(pointTextTab)
                    }
                Essentials14_2WEB()
                    .tabItem {
                        Image(systemName: webImageTab)
                        Text(webTextTab)
                    }
            }
        }
    }
}

#Preview {
    Essentials14_2()
}

struct Essentials14_2Code: View {
    var body: some View {
        ScrollView{
            Text(codeEssentials14_2)
        }
    }
}

#Preview {
    Essentials14_2Code()
}

struct Essentials14_2Points: View {
    var body: some View {
        ScrollView{
            Text(pointEssentials14_2)
        }
    }
}

#Preview {
    Essentials14_2Points()
}

struct Essentials14_2WebView: UIViewRepresentable {
    let searchURL: URL
    func makeUIView(context: Context) -> WKWebView {
        let view = WKWebView()
        let request = URLRequest(url: searchURL)
        view.load(request)
        return view
    }
    
    func updateUIView(_ uiView: WKWebView, context: Context) {
        
    }
}

struct Essentials14_2WEB: View {
    private var url:URL = URL(string: urlEssentials14_2)!
    var body: some View {
        Essentials14_2WebView(searchURL: url)
    }
}

#Preview {
    Essentials14_2WEB()
}

◆iOSApp17DevelopmentEssentialsCh14.swift

import SwiftUI

//ビュー管理構造体
struct ListiOSApp17DevelopmentEssentialsCh14: Identifiable {
    var id: Int
    var title: String
    var view: ViewEnumiOSApp17DevelopmentEssentialsCh14
}

//遷移先の画面を格納する列挙型
enum ViewEnumiOSApp17DevelopmentEssentialsCh14 {
    case Sec1
        //ここを追加
    case Sec2
}

//各項目に表示するリスト項目
let dataiOSApp17DevelopmentEssentialsCh14: [ListiOSApp17DevelopmentEssentialsCh14] = [
    ListiOSApp17DevelopmentEssentialsCh14(id: 1, title: essentialsChapter14_1SubTitle, view: .Sec1),
        //ここを追加
    ListiOSApp17DevelopmentEssentialsCh14(id: 2, title: essentialsChapter14_2SubTitle, view: .Sec2)
]

struct iOSApp17DevelopmentEssentialsCh14: View {
    var body: some View {
        VStack {
            Divider()
            List (dataiOSApp17DevelopmentEssentialsCh14) { data in
                self.containedViewiOSApp17DevelopmentEssentialsCh14(dataiOSApp17DevelopmentEssentialsCh14: data)
            }
            .edgesIgnoringSafeArea([.bottom])
        }
        .navigationTitle(essentialsChapter14NavigationTitle)
        .navigationBarTitleDisplayMode(.inline)
    }
    //タップ後に遷移先へ遷移させる関数
    func containedViewiOSApp17DevelopmentEssentialsCh14(dataiOSApp17DevelopmentEssentialsCh14: ListiOSApp17DevelopmentEssentialsCh14) -> AnyView {
        switch dataiOSApp17DevelopmentEssentialsCh14.view {
        case .Sec1:
            return AnyView(NavigationLink (destination: Essentials14_1()) {
                Text(dataiOSApp17DevelopmentEssentialsCh14.title)
            })
                //ここを追加
        case .Sec2:
            return AnyView(NavigationLink (destination: Essentials14_2()) {
                Text(dataiOSApp17DevelopmentEssentialsCh14.title)
            })
        }
    }
}

#Preview {
    iOSApp17DevelopmentEssentialsCh14()
}

◆TitleManageFile.swift

let essentialsChapter14_2SubTitle = "第2節 辞書(ディクショナリ)"

◆CodeManageFile.swift

let codeEssentials14_2 = """
/**:-------------------
 Essentials 第14章 辞書
 ---------------------*/
var yaoya14_13:[Int: String] = [1:"🍏",2:"🍌",3:"🍇",4:"🍓",5:"🍈",6:"🍍",7:"🍋",8:"🍉"]
print(yaoya14_13[2]!)
//キーと値を分けた配列を結合
var yaoyaKeys14_14 = [1,2,3,4,5,6,7,8]
var yaoyaValues14_14 =
["🍏","🍌","🍇","🍓","🍈","🍍","🍋","🍉"]
var yaoya14_14 = Dictionary(uniqueKeysWithValues: zip(yaoyaKeys14_14, yaoyaValues14_14))
print(yaoya14_14)
print(yaoya14_14.sorted(by: <))
//1から順に番号を振るだけ
var yaoya14_15 = Dictionary(uniqueKeysWithValues: zip(1..., yaoyaValues14_14))
print(yaoya14_15)
var sortedYaoya14_16 = yaoya14_15.sorted{$0.key < $1.key }
print(sortedYaoya14_16)
for element in sortedYaoya14_16 {
    print("\\(element.key):\\(element.value)")
}
//個数
print("項目数は、\\(sortedYaoya14_16.count)だぜ!")
//キーが3の値を呼び出し
print(yaoya14_13[3]!)
//存在しないキーにアクセスしてみると、、、
print(yaoya14_13[9,default:"木梨(キーなし)さん"])
//🍑ちゃんを逆に9キーを作って追加してみる
yaoya14_13[9] = "🍑"
print(yaoya14_13[9,default:"木梨(キーなし)さん"])
print(yaoya14_13)
//🍑から🍐へ
yaoya14_13.updateValue("🍐", forKey: 9)
print(yaoya14_13[9,default:"木梨(キーなし)さん"])
print(yaoya14_13)
//🍐を値のみ削除
yaoya14_13[9] = ""
print(yaoya14_13[9,default:"木梨(キーなし)さん"])
print(yaoya14_13)
//値が空欄判定を行い、空欄の場合はキーごと削除
if yaoya14_13[9] == "" {
    yaoya14_13[9] = nil
    print(yaoya14_13[9,default:"木梨(キーなし)さん"])
    print(yaoya14_13)
}
//7キーを削除
yaoya14_13.removeValue(forKey: 7)
print(yaoya14_13)
//キーと値を使って商品番号と商品名を表示
for (key,value) in yaoya14_13 {
    print("商品番号\\(key)は、\\(value)です")
}
//ソートしたヤツで試すと、、、
for (key,value) in sortedYaoya14_16 {
    print("商品番号\\(key)は、\\(value)です")
}
"""

◆PointManageFile.swift

let pointEssentials14_2 = """
ここでポイント①
ユニークなキーで補完していて、キーには、以下の型しかできないみたいね
・String
・Int
・Double
・Bool

ま、やったことがある人間からしたら、「そりゃそーだし、それだけありゃ十分だろ」って感じなんだけど、やったことがない人にはイメージが湧かないだろうから
"""

◆URLManageFile.swift

let urlEssentials14_2 = "https://note.com/m_kakudo/n/n034b91bea871"

以上。

この記事が気に入ったらサポートをしてみませんか?