Swift3 基本シンタックス 

: Playground - noun: a place where people can play

import UIKit

var str = "Hello, playground"
var ans = 14 + 25 + 36
print(ans)
    ans = 14
        + 25
        + 36
print(ans)

let a = 10
let b = a + 20
print(b)

let a = 10; let b = a+20; print(b)
コメント
var msg = "おはよう"
 msg += "ございます"
print(msg)
let theName =  "太郎"
let theNAME = "次郎"
print(theName)
print(theNAME)
print(theNAME,theName)

let msg1 = "こんにちは"
let msg2 = "ありがとう"
let msg3 = "さようなら"
separator -> 区切り文字の指定
print(msg1,msg2,msg3,separator:"/")
terminator -> インライン化
print("blue","green",separator:"+",terminator:"、")
print("yellow",terminator:"、")
print("red")
定数、変数とは -> e.g 定価と個数が決まってなくても売り上げがわかるなくにも売り上げがわかる -> 定数と変数でアルゴリズムが書けるのが大きな理由

特殊なキーワード #file #line #column #function
print(#file)
print(#line)

■定数、変数とは -> e.g 定価と個数が決まってなくても売り上げがわかるなくにも売り上げがわかる
定数
let name:String = "田中"
let width:Int = 56, heighr:Int = 75 インライン
定数 宣言後に値設定
let rate:Double
let price:Double
rate = 1.02
price = 2500 * rate
 price = 1000 * rate  定数を変更しようとしてエラー

変数
var name:String = "ビジター"
var level:Int = 1, point:Int = 10
name = "鈴木"
point = 50

var kokugo:Int
var sansu:Int
var goukei:Int
kokugo = 56
sansu = 67
goukei = kokugo + sansu 演算子の前後の空白は両方か無し、片側だとエラー
print(goukei)

数値型 整数と浮動小数点 -> それぞれ扱える桁数が違う e.g Int8,UInt8,UInt16... float,Double
文字型と文字列型 -> １文字はCharacter型、文字列はString型 e.g 文字列から１文字取り出す処理などでCharacter型を使う
論理型 -> YES/NO,真/偽,表/裏 true/false どちらか一方を必ずとる
その他の型 -> Array,Dictionary,CFGPoint,UIColor,syruct..
定数と変数の有効範囲 -> {}で括られた中で有効という基本 e.gクラス内で有効なスコープ、メソッド内で有効なスコープ、if文の中で有効なスコープ、else{}で有効なスコープ
型変換（キャスト）
let kosu = 5
let tanka = 2300
let tax = 1.08
let price = tanka * kosu * (1 + tax) この式がエラー -> tanka * kosu をDouble型にキャストする
let price = Double(tanka * kosu) * (1 + tax)
print(price)

数値をStringにキャストする 文字列同士の連結演算子 + が使える
let subject = "理科"
let point = 82
let result = subject + String(point) + "点"
キャスト演算子 as を使う方法もある。Swiftのasはクラスのインスタンスをサブクラスの型にダウンキャストする e.g textField.text! as NSString
サブクラス -> extendsの左側（継承側) スーパークラスextendsの右側（継承元）

定義済みのグローバル定数 
print(M_E,M_LOG2E,M_PI,separator:"/")

数値の最小値と最大値 ->プロパティで調べられる UInt8,16,32,64 ? min:max
print(INT8_MIN,INT8_MAX,UInt8.min,UInt8.max,separator:"/")

***タプル (val1,val2,..)複数の値を1個の値として扱う -> 1個の変数に複数の値を入れたり、関数で複数の値を返すことができる
作成
let product = ("Swift",2014)
var kingaku = (1000,80)
var guest = ("大重","おおしげ","内税")

値の型 -> 個数文型指定する
let product:(String,Int) = ("Swift",2014)
var guest:(String,String,Int)
guest = ("大重","おおしげ",1234) 型を合わせないとエラー

型推論
var kingaku = (1000,80)
kingaku = (1080,"内税") Int推論でエラー

タプルの値を取り出す
let data = (1000,80)
let (price, tax) = data 同じ形のタプルで受け取る
let kingaku = price + tax *足し算実行

使わない値のインデックスにワイルドカードを使う
let data = (1000,80)
let (price, _) = data
print(price)

インデックスでアクセス
let kingaku = (1000,80)
let price = kingaku.0
let tax = kingaku.1
print(price + tax)

インデックスで変更
var user = ("鈴木",29)
user.1 = 30
print(user)

ラベル付き
let kingaku = (price:1000, tax:80)
let seikyugaku = kingaku.price + kingaku.tax
print(seikyugaku)

***ラベル付きタプルを値にもつ変数宣言(わかりにくいが型のみの宣言)
var user:(name:String, age:Int, isPass:Bool)
user.name = "高田"
user.age = 23
user.isPass = true
print(user)
print(user.age)

■演算子
**基本ok 負の値でも剰余演算子が使える
let d = -11%4
print(d) -> -3

整数計算の注意点 -> 以下は６、これを正確に7.5にするには、3を3.0にするか、let ans:Doubleのように型を明示する
let ans = 3 * (10/4)
print(ans)

論理演算子 &&、||、! -> and or not
let a = true
let b = false
let and = a && b
let or = a || b どちらか一方trueならtrueが返る
let not = !a
print(and,or,not)

***実践テク：値の入れ替え -> ***例えばボタン押下時の画像の表示非表示や活性/非活性,フラグ管理 -> btnTapped{imageView.isHidden = !imageView.isHidden}で一発管理

比較演算子 >,<,>=,<=,==,!= 代入演算子 =

*複合代入演算子 +=,-=,*=,/=,%=,&&=,||=  a/=b -> a割るbの結果をaに代入 a&&=b aとbの論理積の結果をaに代入

***三項演算子 ?: -> 条件式?trueの場合の式：falseの場合の式
let a = arc4random_uniform(100)0~99の乱数
let b = arc4random_uniform(100)
let bigger = (a>b) ? a : b
print("aは\(a)bは\(b)biggerは\(bigger)")

**レンジ演算子 ..<, ...  数値の範囲を指定できる演算子 最後の値を含まない場合(未満と以下) ? ..< : ...
整数の範囲
let rangeInt = -5..<5
print(rangeInt.contains(-3)) レンジの範囲に値が含まれているかどうかcontainsで調べる
print(rangeInt.contains(2))
print(rangeInt.contains(5))
print("------------------------")
実数の範囲
let rangeDouble = 0.0...1.0
print(rangeDouble.contains(0.1))
print(rangeDouble.contains(1.0))
print(rangeDouble.contains(1.5))

for-in文でレンジ演算子 -> 1~4回目 ...だと　1~5回目
for i in (1..<5){
    print("\(i)回目")
}

**ビット演算子 2進数,16進数の値を扱う演算子 2進数は0b,16進数は0xが接頭辞 print(0xFF)だと10進数に変換されて255
ビットシフト << a<<b aを左へb桁シフトする , >> a>>b aを右へb桁シフトする  2進数で用いられる概念、左に２桁で値は４倍になる
**ビット積、ビット和、排他的ビット和、ビット否定 a&b,a|b,a^b,a~b
****16進数0x40E0D0をビット積とビットシフトでR,G,Bに分解してturquoise(64,224,208)を取り出す。
let RGB: UInt32 = 0x40E0D0  turquoise(64,224,208)
let red = (RGB & 0xFF0000) >> 16 上位2桁を取り出す
let green = (RGB & 0x00FF00) >> 8 中央の2桁を取り出す
let blue = RGB & 0x0000FF 下2桁を取り出す
print(red,green,blue) RGB値は0~255
実践テク? 255で割って0~1にして、ビューの背景色を設定
let R = CGFloat(red)/255
let G = CGFloat(green)/255
let B = CGFloat(blue)/255

view.backgroundColor = UIColor(red:R,green:G,blue:B))

条件で処理分岐 if文
let tokuten = 85
if tokuten>=80 {
    print("素晴らしい!\(tokuten)点でした!")
}
if else
let tokuten = arc4random_uniform(101) 0~100の乱数生成
    if tokuten >= 60 {
        print("おめでとう合格です。")
    } else {
        print("残念、不合格です。")
    }
    print(tokuten)
if elese if -> 割愛

ネスティングと論理式
let sugaku = arc4random_uniform(101)
let eigo = arc4random_uniform(101)
数学50点以上かつ英語60点以上が合格
if sugaku >= 50 {
    if eigo >= 60 {
        print("合格！")
    } else {
        print("不合格!")
    }
} else {
    print("不合格!")
}
print("数学\(sugaku),英語\(eigo)")

条件式を論理式で書く

let sugaku = arc4random_uniform(101)
let eigo = arc4random_uniform(101)

数学50,英語60以上で合格

if sugaku >= 50 && eigo >= 60 {
    print("合格!")
} else {
    print("不合格!")
}
print("数学\(sugaku),英語\(eigo)")

数学,英語どちらか60以上で合格 -> || 割愛

複数の条件式をカンマで区切って並べる
数学、英語共に50点以上かつ合計が120点以上が合格

func hantei(sugaku:UInt, eigo:UInt) {
    ***複数の条件式をカンマで区切ったif文 -> &&と同じ
    if sugaku>=50, eigo>=50, (sugaku+eigo)>=120 {
        print("合格", terminator: "/")
    } else {
        print("不合格", terminator: "/")
    }
    print("数学\(sugaku),英語\(eigo)、合計\(sugaku+eigo)")
}

hantei(sugaku: 53, eigo: 71)
hantei(sugaku: 56, eigo: 62)
hantei(sugaku: 48, eigo: 79)

switch -> 値のケース文
let theColor = "yellow"
switch theColor {
case "red", "yellow":
    print("赤色と黄色は注意!")
case "green":
    print("緑は快適")
case "gray":
    print("グレーは停止中")
default:
    print("その他は順調")
    
}

****レンジ演算子を使って振り分ける
20回繰り返す
for _ in 1...20 {
    let num = arc4random_uniform(50)  0~49の乱数
    print("\(num)", terminator:"")
     numで振り分ける
    switch num {
    case (10...15):
        print(":交換", terminator: "")
    case 20,(31...35),40:
        print(":再検査", terminator: "")
    default:
        print(":合格", terminator: "")
    }
}
***タプルを利用した振り分け
let size = (6,11)
switch size {
case (0,0):
    print("幅高さ共に0です")
case (5...10, 5...10):
    print("規定サイズです")
case (_, 5...10):
    print("幅\(size.0)が規格外です")
case (5...10, _):
    print("高さ\(size.1)が規格外です")
default:
    print("幅高さ共に規定外です")
    
}

***バリューバインディング ケースで評価する値を定数や変数で受け取る
let size = (4,10)
switch size {
    case (0,0):
        print("幅高さ共に0です")
    case (5...10, 5...10):
        print("規定サイズです")
    case (let width, 5...10): タプルの1番目の値が格納
        print("幅\(size.0)が規格外です")
    case (5...10, let height): タプルの2番目の値をheightが受け取る
        print("高さ\(size.1)が規格外です")
    default:
        print("幅高さ共に規定外です")
    
}

******バリューバインディングとwhereキーワードで値の振り分けに条件式を使えるようになる
let size = (45,40,100)
switch size {
    case let (width,height,_) where (width>=60) || (height>=60):
        print("規定外：幅高さのどちらかが60以上")
    case let (_,_,weight) where (weight>80):
        print("規定外：重さが80以上")
    default:
        print("規定内")
}
defaultが省略になるケース　-> _を使い、全てを網羅している
let aPoint = (50,100)
switch aPoint {
    case (0,0):
        print("中心点です")
    case (0,_):
        print("x軸上の点です")
    case(_,0):
        print("y軸上の点です")
    case let (x,y):
        print("点(\(x),\(y))です")
    
}

fallthrough フォールスルー -> break文の逆のような文、ケースマッチした以降の処理を無条件で行う "a" ->(true,true,true), "b" -> (false,true,true) , "c" -> (false,false,true), "else hoge" -> (false,false,false)

var abc:(a:Bool, b:Bool, c:Bool) = (false,false,false)

let fall = "a"
switch fall {
case "a":
    abc.a = true
    fallthrough
case "b":
    abc.b = true
    fallthrough
case "c":
    abc.c = true
    fallthrough
default:
    print(abc)
}

***for-in文 ->　順に値を取り出す for-in レンジ
5から順に取り出して2をかける 最初のnumは5,次に6...
for num in 5...9 {
    let value = num * 2
    print(value, terminator: ",")
}
単に指定回数繰り返す -> 15回
for _ in 1...15 {
    let num = arc4random_uniform(100)
    print(num, terminator: ",")
}
for-inのネスティング
for i in 0...2 {
    for j in 0...2 {
        let point = (5*i, 10*j)
        print("\(i)-\(j)回目\(point)")
    }
}

****コレクションの値を順次取り出す for-in コレクション
let numList = [3,2,6,5,8,7,9]
var sum = 0
for num in numList{
    sum+=num
}
print("合計:\(sum)")

**飛び飛びで繰り返す for-in stride() -> stride()関数を利用すると「3,6,9,12」のように繰り返しを飛び飛びにすることができる
10から30まで3ずつ増える数値を取り出す
for num in stride(from: 10, to: 30, by: 3){

    print(num, terminator: ",")
}

***ストリングから１文字ずつ取り出す
let message = "おもてなし"
for char in message.characters {
    print(char)
}

*****条件が満たされている間繰り返す while
パワーが100未満でチケットがあればパワーと交換する
var titckets = 5
var power = 30
while (titckets>0) && (power<100) {
    titckets -= 1
    power += 20
}
print("power\(power),残チケット\(titckets)")

*****repeat-while文 他言語のdo -　while文に相当する　-> repeatの中の値がwhile条件がfalseになるまで実行
合計が21になる3個の数値(1~13)の組み合わせを探す
var a:UInt32, b:UInt32, c:UInt32
var total:UInt32
repeat {
    a = arc4random_uniform(13) + 1 1~13の乱数
    b = arc4random_uniform(13) + 1
    c = arc4random_uniform(13) + 1
    total = a+b+c
} while total != 21
print(a,b,c, separator: "+")

******負の値はスキップして正の値だけ足す continue
let vlist = [3,5,-2,6,-8,2]
var total = 0
for v in vlist {
    負の値はスキップする
    if v<0 {
        continue 処理を中断して次の値に進みます
    }
    
    total += v
    print("\(v),")
}
print(total)

繰り返しの中断 break
70より大きな値が出るまで繰り返す
var num:UInt32 = 0
無限に繰り返す
while true {
    num = arc4random_uniform(100)
    if num>70 {
        break
    }
}
print(num)

ループにラベルを付ける -> ラベルを付けることでcontinueやbreakで処理中断後に続ける位置をラベル指定できる　可読性が上がる
xloop:for x in 0...3 {
    yloop:for y in 0...3 {
        if (x<y){
            print("---------")
            continue xloop
        }
        print((x,y))
    }
}

二重配列の値を走査し、マイナスの値が入ってたら中断、break outloopのように外のラベルを指してbreakしている ->内側のループから外側のループをブレイクできる
let vlist:Array = [[4,2],[5],[9,8,10],[6,8,-9],[4,2],[9,3]]
 vlistを走査する
outloop: for alist in vlist {
     allistを走査する
    inloop: for v in alist {
        マイナスの値があれば出力して中断する
        if v<0 {
            print(alist)
            break outloop  inloopだけでなくoutloopも抜けられる
        }
    }
}


func isEven(number:Int) -> Bool {
    guard number <= 10 else {
        return false
    }
    if number % 2 == 0 {
        return true
    }
    
    return false
}

let num:String = "10"
let castNum:Int = Int(num)!

switch castNum {
case  5:
    print(5)
case  10:
    print(10)
default:
    print("other")
}

isEven(number: castNum) 10以下は偶数ならtrue
isEven(number: 9)
isEven(number: 12)  11以上はguardでfalse
print(UInt32.max)
print(Int32.max)
print(Int32.min)

let a:[String] = ["a","b","c"]

for v:String in a {
    print(v)
}

let numArray:[UInt] = [1,2,3]
var sum:UInt = 0

for v:UInt in numArray {
     sum += v
}

print(sum)

/* CHAPTER3 FUNCTION CLOSURE */

引数のない関数 -> 1~6の乱数を5回出力する
func dice() -> Int {
    let number = 1 + arc4random_uniform(6)  0~5
    return Int(number)
}

for _ in 1...5 {
    let num = dice()
    print(num)
}
戻り値がない関数 以下のhello()は３つの書式でかける
func hello(){
    print("hello")
}
func hello() -> Void{
    print("hello")
}
func hello() -> () {
    print("hello")
}

関数の処理を途中で抜ける guard-else文 guarc 条件式 else {return}
func half(num:Double){
    中断処理
    guard num>=10 else {
         numが10以上でないとき関数から抜ける
        return
    }
    値を半分にして出力する
    let halfNum = num / 2
    print("\(num)の半分は\(halfNum)")
}
half(num: 25)
half(num: 9) guard文で処理中断
half(num: 12)

処理を抜ける前に必ず実行する defer文
func half(num:Double) {
    最後に必ず実行する
    defer {
         print("計算終了")
    }
    中断処理
    guard num>=10 else {
        num>=10がfalseのとき中断
        return
    }
    値を半分にして出力
    let halfNum = num/2
    print("\(num)の半分は\(halfNum)")
}
half(num: 25)
half(num: 9) half(num:9)は中断されますが、defer文は実行される -> print("計算終了")のみ出力
half(num: 12)

引数がある関数
人数分の料金を計算する
func pricel(ninzu:Int) -> Int {
    let tanka = 1200
    let result = tanka * ninzu
    return result
}
５人分の計算
let price = pricel(ninzu: 5)
print(price)

単価と人数を引数にする
func price2(ninzu:Int, tanka:Int) -> Int {
    return tanka * ninzu
}
print (price2(ninzu: 3, tanka: 1300))

******引数を合計する -> 型名の後ろにレンジ演算子のような記述で受け取った引数が配列化する
func sum(numbers:Double...) -> Double {
    var total:Double = 0.0
    引数はnumbersに入っている
    for num in numbers {
        total += num
    }
    return total
}
let goukei = sum(numbers: 5,6,7,8,9)
print(goukei)

引数に初期値を設定する

func greeting(who:String = "お客様") -> String {
    return who + "、こんにちは"
}
print(greeting())
引数を与えた場合
print(greeting(who: "田中様"))

複数の引数に初期値がある
func price3(tanka:Int, kosu:Int = 1, souryou:Int = 250) -> Int {
    return tanka * kosu + souryou
}
print(price3(tanka: 1000))
print(price3(tanka: 1000,kosu: 2))
print(price3(tanka: 2500,souryou: 1500))
print(price3(tanka: 1200, kosu: 5, souryou: 0))

******複数の戻り値がある関数 -> 戻り値にタプルを利用することで実現する
func testResult(kokugo:Int, sugaku:Int, eigo:Int) -> (total:Int, average:Double) {
    ３科目合計
    let total = kokugo + sugaku + eigo
    3科目平均
    var ave:Double = Double(total/3)
    小数点以下１位で四捨五入 -> ※小数点第二位を四捨五入の時は100倍してから実行し、100で割る...
    ave = round(ave*10)/10
    return (total,ave) タプルでreturn
}
let result = testResult(kokugo: 80, sugaku: 68, eigo: 72)
print("合計\(result.total)") 配列と同じように添え字でアクセス
print("平均\(result.average)")

外部引数名を付ける ->　ブロック内では内部引数 kg,cm を利用する
func bmi(weight kg:Double, height cm:Double) -> Double {
    if cm == 0 {return -1}
    体重(kg)を身長(m)の2乗で割る -> bmi
    var result = kg/pow(cm*0.01, 2) pow関数は累乗を求める。センチメートルをメートル化して２乗する
    小数点以下１位で四捨五入する
    result = round(result*10)/10
    return result
}
外部引数で呼び出し
bmi(weight: 100, height: 170)
bmi(weight: 75, height: 170.8)
bmi(weight: 100, height: 0)
bmi(weight: 0, height: 0)
外部引数名が_の関数　-> 呼び出し時に省略
func traiangleArea(_ width:Double, _ height:Double) -> Double {
    let result = width * height / 2
    return result
}
三角形の面積 -> 引数なしで実行できる
print(traiangleArea(30, 16.5))

オーバーロード(関数の多重定義)
 a,bの引数
func calc(a:Int, b:Int) -> Int {
    return a+b
}
 c,dの引数
func calc(c:Int, d:Int) -> Int {
    return c*d
}
 a.b.cの引数
func calc(a:Int, b:Int, c:Int) -> Int {
    return (a+b)*c
}
引数の違いで同名のメソッドでも区別される
let ans1 = calc(a: 2, b: 3)
let ans2 = calc(c: 2, d: 3)
let ans3 = calc(a: 2, b: 3, c:4)

****ジェネリクスな関数 -> <T>は型パラメータと呼ぶ 呼び出し側のデータ型にとらわれることなく処理ができる
引数で受けた値にその時点の日時を付けたタプルを付加して、タプルで返す
func makeTuple<T>(value:T) -> (id:T, date:NSDate) {
    let now = NSDate()
    return (value, now)

}
引数の型
let tuple1 = makeTuple(value: "abc")
let tuple2 = makeTuple(value: 123)
print(tuple1)
print(tuple2)
print(tuple1.id)
print(tuple2.date)

変数に関数を代入する
func calc(tanka:Int, kosu:Int) -> Int {
    return tanka * kosu
}
let myCalc = calc(tanka:kosu:)
let kingaku = myCalc(280,4) calc()と同じ関数になる
print(kingaku)
*****関数を引数にする -> 引数で関数の型を記載する
func message(user:String, msgFunc:(String) -> String) -> String {
    let msg = msgFunc(user)  引数で受け取った関数を使って実行する
    return msg
}

引数として渡す関数 -> hello(),bye()
func hello(user:String) -> String {
    return ("\(user)さん、ハロー")
}
func bye(user:String) -> String {
    return ("\(user)さん、バイ!")
}
関数名を渡す
let msg1 = message(user: "田中", msgFunc: hello)
let msg2 = message(user: "鈴木", msgFunc: bye)
print(msg1)
print(msg2)

*****関数を関数の値として返す -> 関数を戻り値 (Int) -> Int
func priceFunc(age:Int) -> (Int) -> Int {
    if age<16 {
        return kids
    } else {
        return adult
    }
}

子供の計算
func kids(kazu:Int) -> Int {
    return 400*kazu
}
大人の計算
func adult(kazu:Int) -> Int {
    return 600*kazu
}

priceFuncを10歳と18歳で試す
    年齢で使用する関数を取り出す
    let age10 = priceFunc(age: 10)
    let age18 = priceFunc(age: 18)
    それぞれの関数で人数を指定する ※引数名は省略されている
    let kingaku1 = age10(1)
    let kingaku2 = age18(2)
    print(kingaku1)
    print(kingaku2)

********関数のネスティング -> 先ほどの値によって実行する関数を選りわけたのを整型する
***記述順序注意!!先に子要素の関数をブロック内に記述(定義)して、その下部に親処理で関数名を振り分ける
func priceFunc(age:Int) -> (Int) -> Int {
    
    子供の計算
    func kids(kazu:Int) -> Int {
        return 400*kazu
    }
    大人の計算
    func adult(kazu:Int) -> Int {
        return 600*kazu
    }

    戻す関数を年齢で振り分ける
    if age<16 {
        return kids  メソッド名だけでいい
    } else {
        return adult
    }
    
}
    ****かなりいけてる呼び出し方(自称) -> ネストした関数でまず親関数の引数指定、次いで内部関数の引数指定
    let age10 = priceFunc(age: 10)(1)
    let age18 = priceFunc(age: 18)(2)

    print(age10)
    print(age18)

****クロージャ -> 名前のない(funcがない)関数のオブジェクトで、変数に代入したり、引数の値として関数に渡したりする。クロージャを引数に指定する関数は少なくない。直感的にかけるメリット?
戻り値がある書式 {()->() in statement return statement}
変数に代入
let myFunc:(Int,Int) -> Int = {(a:Int, b:Int) -> Int in
    return a + b
}
let ans = myFunc(1,2) **引数名は不要
print(ans)

**********クロージャを引数で受け取る関数 -> map関数(指定の配列に入っているすべての値に対し処理実行)にクロージャ引数を渡す
let numbers = [4,7,2,9]
    配列のすべての値を２倍にする
    let array1 = numbers.map({(v:Int) -> Int in
        return v*2
    })
    print(array1)
    別書式 -> map関数の引数を省略した形で接尾クロージャという
    let array2 = numbers.map{(v:Int) -> Int in
        return v*2
    }
    print(array2)
    さらに型推論と１行ステートメントのreturn省略を使った書式
    let array3 = numbers.map{v in v*2}
    print(array3)
    クロージャの引数の値は順に$0,$1,$2...と参照できる。このサンプルでは第1引数を２倍することでmapメソッドが配列内を走査し、期待結果を得れる
    let array4 = numbers.map{$0 * 2}
    print(array4[1])
 ストリングの配列処理
let colors:[String] = ["Red","Blue","Green"]
すべての文字を小文字にする
let colorsSmall = colors.map{str in str.lowercased()}
print(colors)
print(colorsSmall)
簡略化した別書式
let colorSmall2 = colors.map{$0.lowercased()}
print(colors)
print(colorsSmall)

/* CHAPTER3 String */
""で囲むだけで作れる、またString("")のようにも書ける
let hello = String("ハロー") + String(2000+20) + "さん"
print(hello)
空のストリング
let emptyString = String()
var str = "Hello"
str = ""
print(str)
空ならば中断する
func hello(_ who:String){
    if who.isEmpty {return}
    let msg = "ハロー!" + who + "さん"
    print(msg)
}
hello("")
hello("田中")
同じ文字の繰り返し
let stars = String(repeating:"★", count: 10)
print(stars)
ストリングに改行とダブルクォーテーションを入れる
let swift = "Swiftとは\n\"アマツバメ\"です。"  \nで改行、\"アマツバメ"\でクォーテーションをエスケープ
print(swift)
ストリングの文字数 -> characters.count
let str = "あいうえお12345ABcde(^_^)" 5*4
print(str.characters.count)
ストリングに変数や式を含める -> "\()"
let entries = 24
let staff = 3
let str1 = "参加者\(entries)人。"
let str2 = "スタップを含めると\(entries + staff)です。"
print(str1)
print(str2)
ストリングを連結する
let name1 = "海原"
let name2 = "次郎丸"
let str = name1 + name2 + "さん"
print(str)
let week = ["日","月","火","水","木","金","土"]
let renketu = [String]()
print(renketu.append(week.map{$0})
var oneweek = ""
for day in week {
    oneweek += day
}
print(oneweek)
ストリングを数値に変換する
let kakaku:String = "240"
let kosu:String = "2"
let kingaku = Int(kakaku)! * Int(kosu)!  アンラップする -> kakaku = "abc"の場合などはnilになって落ちる。オプショナル型となっている。
print(kingaku)
ストリングを小数に変換して計算する
let r = "20"
let pai = "3.14"
let menseki = Double(r)! * Double(r)! * Double(pai)!
print(menseki)
数値をストリングに変換する -> String() or descriptionプロパティ
let nakami = 135.5
let packege = 12.0
let str1 = "内容量：" + String(nakami) + "g"
let str2 = "総重量：" + (nakami + packege).description + "g"
print(str1)
print(str2)
**ストリングから文字を取り出す
*インデックスを調べる
let str = "Swift入門ノート"
var start = str.startIndex
var end = str.endIndex
*先頭の文字を取り出す
let topChar = str[start]
print(topChar)  *この時1文字なのでchar型　ストリングで連結するにはストリングに変換し直す
let result = "先頭の文字は「" + String(topChar) + "」です。"
print(result)
一つ先のインデックスを取得
start = str.index(after: start)
print(str[start])
一つ手前のインデックス取得
end = str.index(before: end)
print(str[end])
**指定のインデックス
let index = str.index(str.startIndex, offsetBy: 5) 先頭から５文字目 ※ゼロからカウント
let index2 = str.index(str.endIndex, offsetBy: -4) 末尾から4文字目
print(str[index])
print(str[index2])
レンジ演算子でインデックス範囲
let str1 = str[start...end] start -> インデックス1から
let str2 = str[start..<end]
インデックスの手前/後ろのストリングを取り出す
print(str[index])
let str3 = str.substring(to: index)
let str4 = str.substring(from: index)
****先頭文字だけを大文字にする
func cap(_ str:String) -> String {
    1文字目
    let start = str.startIndex
    let chr = str[start]
    let str1 = String(chr)
    ２文字目以降
    let second = str1.index(after: start)
    let str2 = str.substring(from: second) 最初行こうの文字列取り出す
    1文字目を大文字、残りを小文字にして連結する
    return str1.uppercased() + str2.lowercased()
}

let str1 = cap("apple")
let str2 = cap("APPLE")
print((str1,str2))

ストリング同士の比較 -> 演算子を使える if文の条件式などで str1 == str2 , str1 > str2 
大文字小文字を区別せず

let str1 = "apple"
let str2 = "Apple"
すべて小文字で比較する ***※単に==と比較した場合、等価ではなく"同じではありません。"を通過する
if str1.lowercased() == str2.lowercased() {
    print("str0とstr1は同じです")
} else {
    print("stroとstr1は同じではありません。")
}

******前方一致、後方一致
*****前方、後方一致で値を振り分ける
let itemList = ["カツ丼","カツカレー","親子丼","天丼"]
String型の空の配列を作る
var menu1 = [String]()
var menu2 = [String]()
for item in itemList {
    "カツ"で始まるアイテム
    if item.hasPrefix("カツ"){
        menu1.append(item) menu1に追加
    }
    "丼"で終わるアイテム
    if item.hasSuffix("丼"){
        menu2.append(item)
    }
}
print(menu1)
print(menu2)

ストリングに含まれているかどうか -> contains()
let str1 = "我輩は黒猫である"
let str2 = "黒猫"
if str1.contains(str2) {
    print("「\(str2)」が含まれています。")
} else {
    print("「\(str2)」が含まれていません。")
}
****見つかった範囲の後ろを取り出す -> rangeで見つけたい位置、upperBondで後ろの範囲
let str = "東京都千代田区神南1-2-3"
let result = str.range(of: "東京都")
if let theRange = result {
     rerultがnil出なかった時
    let afterStr = str.substring(from: theRange.upperBound)
    print(afterStr)
} else {
    print(str)
}
見つかった範囲を削除する
var str = "東京都千代田区神南1-2-3"
let result = str.range(of: "東京都")
if let theRange = result {
    str.removeSubrange(theRange)
}
print(str)
/* CHAPTER5 Array*/
生成(型推論)
let strArray = ["a","b","c","d","e"]
let intArray = [1,2,3,4,5]
var boolArray = [true,false,true,false,false]
var tupleArray = [(0,0),(100,120),(180,200)] tuple型でも要素数とデータ型は揃える必要がある ※型推論以後は同一型でないと要素になれない
値の型を限定した配列を作る
let colors:[String] = ["red","green","blue"]
let numList:[Int] = [1,2,3]
let resultList:[Bool] = [true,false,true]
*Array<値の型>を使った配列を作る　※関数の定義時に必要となる書き方
let colors:Array<String> = ["red","blue","green"]
let numLiost:Array<Int> = [12,32,34,34]
let resultList:Array<Bool> = [true,false,true,false]

*空の配列
var strArray = [String]()
var intArray = [Int]()
var doubleArray = [Double]()
空かどうか調べる
var theArray = [1,2,3]
theArray = []
if theArray.isEmpty {
    print("theArrayは空の配列です")
}
配列の個数
let aArray = [11,22,33,44,55]
print(aArray.count)
**配列を同じ値で初期化する -> 配列の初期値をすべて０で埋めたい,**生成と同時にパラメーターを渡してる
let zeroList = [Double](repeating:0.0, count:10)
let cList = [String](repeating:"未設定", count:5)
print(zeroList)
print(cList)

*****連続番号が入った配列を作る -> レンジ演算子
let numbers = [Int](-3...3)
print(numbers)
5~9が入った配列
let numbers = Array<Int>(5..<10)
配列と配列を連結する -> 配列同士でも同型なら演算子が使え、末尾に要素が加わる
let basicCourse = ["ラン", "スイム"]
let fullCourse = basicCourse + ["バイク", "カヌー"]
print(basicCourse)
print(fullCourse)
配列から値を取り出す
let abcArray = ["a","b","c","d","e","f","g","h","i"]
let str1 = abcArray[0]
let str2 = abcArray[2]
***レンジで一気に取り出す
let newArray = abcArray[4...6]
配列の値を入れ替える
var theArray = ["a","b","c","d","e","f","g","h","i"]
theArray[0] = "あ"
theArray[2] = "いう"
レンジで4~6のインデックスを置き換える***この時要素数は５つ加えている点に注意！一致してなくてもその位置に加えられる！
theArray[4...6] = ["赤","白","黄色","青","緑"]
print(theArray)

多次元配列(配列のネスティング)
値操作
var nestArray = [["a1","a2","a3"],["b1","b2","b3"],["c1","c2","c3"]]
let theValue = nestArray[1][2]
nestArray[2][0] = "Hello"
print(theValue)
print(nestArray)
*****配列からすべての値を取り出す
let numArray = [53,45,67,81,77]
var sum = 0
var min = Int.max
var max = Int.min
numArrayからすべての値を１つずつ取り出す
for item in numArray{
    sum += item
    if item<min {
        min = item *****小さい方に置き換える ->　*****コレクション走査中に次々プロパティを変更する
    } else if item>max {
        max = item *****大きい方に置き換える ->　*****コレクション走査中に次々プロパティを変更する
    }
}
平均を求める
let ave = Double(sum)/Double(numArray.count)
print("合計\(sum)、平均\(ave)、最小\(min)、最大\(max)")

**インデックス番号と値を取り出す -> タプル引数にenumerated()で配列のインデックス番号を値と同時に取り出せる
let colorList = ["bulew", "yellow", "red", "green"]
for (index, value) in colorList.enumerated() {
    print((index,value))
}
最初の値と最後の値を取り出す -> first/lastプロパティ
let emptyArray = [Int]()
let abcArray = ["a","b","c","d"]
print("先頭は\(emptyArray.first)、最後は\(emptyArray.last)")
print("先頭は\(abcArray.first!)、最後は\(abcArray.last!)")

*****値をソートする -> array.sort() は昇順
var ageArray = [34,56,12,32,1]
ageArray.sort()
print(ageArray)
sort()が元配列の昇順並び替えに対して、sorted()はソート後に配列を新たに生成
let fruits = ["orange","appple","pineapple","banana"]
let fruitsSorted = fruits.sorted() ソート配列生成
print(fruits)
print(fruitsSorted)

配列の値の追加と削除
追加するなのでvar宣言
appendは割愛
insert
var aList = ["a","b","c","d"]
aList.insert("xyz", at: 2) インデックス指定してその手前に
print(aList)
delete
var aList = ["a","b","c","d"]
aList.remove(at: 2) インデックス指定
print(aList)
他にも先頭はremoveFirst(),最後はremoveLast(),すべての値削除はremoveAll()のインスタンスメソッドがある
***配列の複製
参照渡しでなくコピー(値渡し?)が作られる
var array1 = [1,2,3]
let array2 = array1  コピーされる
array1[0] = 99 １を書き換え
print("array1\(array1)")
print("array2\(array2)")