Nuxt.js でredirect
- middleware/redirect.js
export default function({ route, redirect }) { const currentPath = route.path; if (currentPath === '/') { redirect('/jp'); return; } }
- nuxt.config.js
router: { middleware: 'redirect' },
ref
新規Railsプロジェクトの作成手順のメモ
$ mkdir project_name $ cd project_name $ bundle init $ echo "gem 'rails'" >> Gemfile $ bundle install --path vendor/bundle --jobs=4 $ bundle exec rails new . -B -d mysql --skip-turbolinks --skip-test --api # -B: bundle installを行わないようにする # DB はmysqlを使用 # turbolinks オフ # minitestを使わない # API モード
参考
rails new
- The Rails Command Line — Ruby on Rails Guides
- rails newの手順を毎回忘れるので記録
- 新規Railsプロジェクトの作成手順まとめ
- Ruby on Rails 5のAPIモードと非APIモードのファイル差分
- Bundlerで並列処理??bundle installを爆速で処理する方法。
.gitignore
linuxのサーバでcronでコマンドを定期実行する
- cron は決められた時間にコマンドを実行するデーモン(Unix系のOSで、主にバックグラウンドで動作するプロセス)
- ユーザーが直接コマンドをプロンプトに入力しなくても希望の時間に特定のコマンドを実行するための仕組み
- cronはデーモンとしてシステム起動時に立ち上がる
/etc/crontab
./etc/cron.d/*
,/var/spool/crontab/*
のcron job
と呼ぶコマンドを羅列したファイルを読み込み指定された時間に実行する
$ vim /etc/crontab SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root HOME=/ # For details see man 4 crontabs # Example of job definition: # .---------------- minute (0 - 59) # | .------------- hour (0 - 23) # | | .---------- day of month (1 - 31) # | | | .------- month (1 - 12) OR jan,feb,mar,apr ... # | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat # | | | | | # * * * * * user-name command to be executed
$ ll /etc/cron.d -rw-r--r-- 1 root root 113 Sep 29 2016 0hourly -rw-r--r-- 1 root root 108 Sep 18 2014 raid-check -rw-r--r-- 1 root root 176 Nov 1 2014 update-motd
* cronのプロセスは以下で確認
$ ps ax | grep cro[n] 2647 ? Ss 0:00 crond
For CentOS
$ service crond status crond (pid 2647) is running...
For Ubuntu
$ service cron status
毎日深夜AM4:00にrootユーザでunix コマンドを実行する場合は以下の2つの方法どちらかで設定できる
$ sudo vim /etc/crontab
SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root HOME=/ # For details see man 4 crontabs # Example of job definition: # .---------------- minute (0 - 59) # | .------------- hour (0 - 23) # | | .---------- day of month (1 - 31) # | | | .------- month (1 - 12) OR jan,feb,mar,apr ... # | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat # | | | | | # * * * * * user-name command to be executed 0 4 * * * root touch /hoge.md
OR
$ sudo su root # crontab -l no crontab for root # crontab -e
0 4 * * * touch /hoge.md
$ crontab -l 0 4 * * * touch /hoge.md
reference from
Trello APIで特定のboardのlabelを削除する
背景
trello のボードを整理したくて、labelを削除しようと思ったけど、量が多すぎて萎えて、scriptでやろうと思った
コード
require 'trello' require 'dotenv' Dotenv.load Trello.configure do |config| config.consumer_key = ENV['TRELLO_CONSUMER_KEY'] config.consumer_secret = ENV['TRELLO_CONSUMER_SECRET'] config.oauth_token = ENV['TRELLO_OAUTH_TOKEN'] end # hogeというボードのurl( https://trello.com/b/qWsxtqhF/hoge ) の qWsxtqhF の部分がboard id BOARD_ID = "qWsxtqhF" board = Trello::Board.find(BOARD_ID) label_ids = board.labels.map(&:id) label_ids.each do |id| label = Trello::Label.find(id) label.delete puts "delete label #{id} done!" end
dotenvの使い方についてはこちら
認証まわりについてはこちら
所感
reference from
Swift ざっくり文法 (4)
- Class
import Foundation class Myclass { let msg:String let name:String? init(msg:String = "hello") { self.msg = msg self.name = nil } init(msg:String = "hello", name:String) { self.msg = msg self.name = name } func hello() { var helloMsg:String if let user = name { helloMsg = user + "san" + msg } else { helloMsg = msg } print(helloMsg) } }
import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. let myObj = Myclass() myObj.hello() // hello let myObjWithMsg = Myclass(msg: "good night") myObjWithMsg.hello() // good night let myObjWithName = Myclass(name: "Alex") myObjWithName.hello() // Alex、hello let myObjWithMsgAndName = Myclass(msg: "good night", name: "Alex") myObjWithMsgAndName.hello() // Alex、good night } --- }
- Convenience initializer
class Myclass { let msg:String let name:String? - init(msg:String = "hello") { - self.msg = msg - self.name = nil - } - init(msg:String = "hello", name:String) { + init(msg:String, name:String) { self.msg = msg self.name = name } + convenience init (msg:String = "hello") { + self.init(msg: msg, name: "Anonymous") + } }
class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. let myObj = Myclass() - myObj.hello() // hello + myObj.hello() // Anonymous, hello let myObjWithMsg = Myclass(msg: "good night") - myObjWithMsg.hello() // good night + myObjWithMsg.hello() // Anonymous, good night - let myObjWithName = Myclass(name: "Alex") - myObjWithName.hello() // Alex、hello let myObjWithMsgAndName = Myclass(msg: "good night", name: "Alex") myObjWithMsgAndName.hello() // Alex、good night } }
convenience initializerを使うと、複数のinitializerがあるときに、別のinitializerを呼ぶことができる。
- stored property と、computed property
- stored propertyは、定数・変数で定義される
- computed propertyは、関数を介して値をやり取りする。値を保持しておらず、設定値を内部的に宣言しておいた定数や変数に設定して保管する
class Circle { var radius:Double = 1.0 // stored property var area:Double { // computed property get{ // property への参照 return radius * radius * Double.pi } set(meseki){ // property への値の設定 radius = sqrt(meseki / Double.pi) } } } let myCicle = Circle() print("\(myCicle.radius)") // 1.0 print("\(myCicle.area)") // 3.14159265358979 myCicle.area *= 2 print("\(myCicle.radius)") // 1.4142135623731 print("\(myCicle.area)") // 6.28318530717959 myCicle.radius = 3.0 print("\(myCicle.radius)") // 3.0 print("\(myCicle.area)") // 28.2743338823081
read only の property
class Circle { var radius:Double = 1.0 var area:Double { get{ return radius * radius * Double.pi } - set(meseki){ - radius = sqrt(meseki / Double.pi) - } } } let myCicle = Circle() myCicle.radius = 3.0 print("\(myCicle.radius)") // 3.0 print("\(myCicle.area)") // 28.2743338823081 + myCicle.area = 300 // error: cannot assign to property: 'area' is a get-only property
Read onlyであれば以下のようにも書ける
class Circle { var radius:Double = 1.0 var area:Double { - get{ return radius * radius * Double.pi - } } }
- property observer ( propertyに値がsetされたことをwillSet, didSetで知ることができる )
- willSetは値が更新される直前に呼ばれ、新しくsetされる値に
newValue
でアクセスできる - didSetは値が更新された直後に呼ばれ、更新前の値に
oldValue
でアクセスできる
- willSetは値が更新される直前に呼ばれ、新しくsetされる値に
class Player { var times = 0 var level:Int { willSet { print("------") print("willSet \(newValue)") } didSet { if oldValue != level { times += 1 print("\(times) update\n\(oldValue) -> \(level)") } else { print("no changes") } } } init () { level = 0 } } var thePlayer = Player() thePlayer.level = 10 thePlayer.level = 10 thePlayer.level = 20 // ------ // willSet 10 // 1 update // 0 -> 10 // ------ // willSet 10 // no changes // ------ // willSet 20 // 2 update // 10 -> 20
- Class property
class Car { static var count = 0 var moving = false func start() { Car.count += 1 moving = true } func stop() { if Car.count > 0 { Car.count -= 1 moving = false } } } let car1 = Car() let car2 = Car() print("\(Car.count)") // 0 car1.start() car2.start() print("\(Car.count)") // 2 car2.stop() print("\(Car.count)") // 1
- Computed class propety
class MyClass { static var radian:Double = 0.0 class var degree:Double { get { return radian * 90/Double.pi } set(dosu){ radian = dosu * Double.pi/90 } } } MyClass.degree = 18 let katamuki = MyClass.degree print("\(katamuki)") // 18.0 MyClass.radian = Double.pi/2 let katamuki2 = MyClass.degree print("\(katamuki2)") // 45.0
- Class method
class Message { class func hello() -> String { return "hello" } } let msg = Message.hello() print(msg)
- Access Right
- access rightを省略すると
internal
になる。 - class が
fileprivate
だと、property/methodをinternal
にすることはできない。 - fileprivate(set) だとfile外からは、read onlyになる
- access rightを省略すると
access right | --- |
---|---|
open | --- |
public | Inheritanceとoverrideができない。 |
internal | module外からアクセスできない |
fileprivate | ファイル外からアクセスできない |
private | class外からアクセスできない |
- Extension
class Player { var name:String = "" func hello() { print("やあ!" + name) } } extension Player { var who:String { get { return name } set(value) { name = value } } func bye() { print("good bye " + name) } } let obj = Player() obj.who = "sam" // やあ!sam obj.hello() obj.bye() // good bye sam
- Inheritance
- A classを継承したB classを作成する。
- A class は、B classのsuperclass
- B class は、A classのsubclass
- B class -> A class
- 1つのclassが直接継承できるclassは一個だけ
- A classを継承したB classを作成する。
--- class ViewController: UIViewController { --- }
override func viewDidLoad() { // superclass のviewDidLoad()を上書き super.viewDidLoad() // superclassのメソッドを実行 // Do any additional setup after loading the view, typically from a nib. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. }
- final ( 継承を禁止したいclass, override されては困るメソッドに付ける。 )
final class MyClass { func hello() { print("hello") } }
class MyClass { final func hello() { print("hello") } }
- Protocol ( classが必ず実装しなければならないpropertyやmethodを指定した仕様書のようなもの。実装しないとエラーになる。 )
- 読み書き可能なpropertyには、
{get set}
をつける - protocolは他のprotocolを継承できる
- 読み書き可能なpropertyには、
protocol GameProtocol { var gamePoint:Int {get} func hit() func miss() } - class MyGame:GameProtocol { + class MyGame:GameProtocol { // protocol requires function 'miss()' with type '() -> ()'; do you want to add a stub? private var total = 0 var gamePoint: Int { return total } func hit() { total += 10 print("hit! +10") } - func miss() { - total /= 2 - print("you miss, half") - } + // func miss() { + // total /= 2 + // print("you miss, half") + // } } let myGameObj = MyGame() myGameObj.hit() // hit! +10 print(myGameObj.gamePoint) // 10 myGameObj.miss() // you miss, half print(myGameObj.gamePoint) // 5 myGameObj.hit() // hit! +10 print(myGameObj.gamePoint) // 15
- Enumeration ( 複数の値を一つの型として宣言するために使用。Swiftの列挙型は値だけではなく、propertyやメソッドを持つことができる。)
enum MensSize { case S case M case L case XL } enum WomenSize { case XS, S, M, L } var mySize = MensSize.M mySize = .S // 型推論で、mySizeは、MensSize型になる var herSize:WomensSize herSize = .XS print(mySize) // S print(herSize) // XS
enum Direction:Int { case forward = 1 case backword // 2 case right // 3 case left // 4 } let muki1 = Direction.forward let muki2 = Direction.backword let muki3 = Direction.right let muki4 = Direction.left print(muki1.rawValue) // 1 print(muki2.rawValue) // 2 print(muki3.rawValue) // 3 print(muki4.rawValue) // 4
let muki5 = Direction(rawValue: 3) if let muki = muki5 { // muki5はnilかもしれないので、Optional Bindingになっている。 print(muki) }
- Enum で型を列挙する
enum Pattern { case Monotone(_:PColor) case Border(color1:PColor, color2:PColor) case Dots(base:PColor, dot1:PColor, dot2:PColor) enum PColor:String { case red = "red" case green = "緑" case yellow = "yellow" case white = "白" } } let shirt1 = Pattern.Monotone(.red) let shirt2 = Pattern.Border(color1: .white, color2: .red) let shirt3 = Pattern.Dots(base: .yellow, dot1: .white, dot2: .green)
- Propertyを持ったEnum
enum Ticket { case Gold, A, B static var name = "入場券" var area:String { get { switch self { case .Gold: return "Gold sheet" case .A: return "A sheet" case .B: return "B sheet" } } } var price:Int { get { switch self { case .Gold: return 24000 case .A: return 5000 case .B: return 2000 } } } } Ticket.name = "hoge live" print(Ticket.name) // hoge live let ticket = Ticket.A print(ticket) // A print(ticket.price) // 5000 print(ticket.area) // A sheet
- Methodを持ったEnum
enum Signal:String { case Green = "green" case Red = "red" var color:String { return self.rawValue } static func description() -> String { return "red or green signal" } func isRun() -> Bool { if self == .Green { return true } else { return false } } mutating func turn() { // 自身を変更するメソッドには `mutating` をつける必要がある if self == .Green { self = .Red } else { self = .Green } } } let text = Signal.description() print(text) // red or green signal var lamp = Signal.Green print(lamp.color) // green print(lamp.isRun()) // true lamp.turn() print(lamp.color) // red print(lamp.isRun()) // false
- Struct ( classと違って継承はできない )
struct Box { let width:Int let height:Int let size:String let tanka:Int var kosu:Int var price:Int { return tanka*kosu } init(width:Int, height:Int, tanka:Int, kosu:Int){ self.width = width self.height = height self.tanka = tanka self.kosu = kosu if (width+height) < 250 { size = "M" } else { size = "L" } } func sellprice(nebiki:Int = 0) -> Int { return price - nebiki*kosu } mutating func discount(count: Int) { kosu -= count } } var box = Box(width: 120, height: 80, tanka: 700, kosu: 6) print(box) // Box(width: 120, height: 80, size: "M", tanka: 700, kosu: 6) let selling_price = box.sellprice(nebiki: 10) print(selling_price) // 4140 box.discount(count: 5) print(box) // Box(width: 120, height: 80, size: "M", tanka: 700, kosu: 1)
- Structのcopy
- Structはclassのobjectと違って、参照型ではなく、値型
- つまりvariable aに入っているStructをvariable bに代入すると参照ではなく、値が複製されて新しいStructとして代入される
- String, Array, DictionaryはStruct、だから参照型ではなく、値型
class BoxClass { var color:String = "red" } struct BoxStruct { var color:String = "red" } // class let cBox1 = BoxClass() let cBox2 = cBox1 cBox2.color = "green" // struct let sBox1 = BoxStruct() var sBox2 = sBox1 sBox2.color = "green" print("cbox1: \(cBox1.color)") // green print("cbox2: \(cBox2.color)") // green print("sbox1: \(sBox1.color)") // red print("sbox2: \(sBox2.color)") // green
Structのsubscript
Struct, subscript
struct Stock { var name:String var data:[String:Int] = [:] init(name:String){ self.name = name } subscript(color:String, size:Double) -> Int { get { let key = color + String(size) if let value = data[key] { return value } else { return 0 } } set { let key = color + String(size) data[key] = newValue } } } var shoes = Stock(name: "Tiger") shoes["green", 24.5] = 3 shoes["green", 25.0] = 5 shoes["red", 26.0] = 5 print(shoes.name) // Tiger print(shoes["green", 24.5]) // 3 print(shoes["green", 25.0]) // 5 print(shoes["red", 26.0]) // 5 shoes["green", 24.5] -= 2 print(shoes["green", 24.5]) // 1 print(shoes["black", 24.5]) // 0
- Structのprotocol
protocol Monster { var monsterName:String {get} var hp:Int {get set} mutating func updateHP(pt:Int) } struct Bokemon: Monster { private(set) var monsterName: String // propertyがread onlyなので、private(set)を付ける var hp: Int mutating func updateHP(pt: Int) { hp += pt } } var monster = Bokemon(monsterName: "swifty", hp: 200) print(monster.monsterName) // swifty print("HP \(monster.hp)") // 200 monster.updateHP(pt: 30) print("HP \(monster.hp)") // 230
reference from
Swift ざっくり文法 (3)
- 関数定義
func dice() -> Int { let num = 1 + arc4random_uniform(6) return Int(num) }
// メソッド定義(戻り値がない関数をメソッドと呼ぶ) func hello() { print("hello") } or func hello() -> Void { print("hello") }
- guard-else ( 条件を満たさないときに実行される )
func half(num: Double){ - if (num < 10) { + guard num>=10 else { return } let halfNum = num/2 print("\(num)の半分は\(halfNum)") } half(num: 25) // 25.0の半分は12.5 half(num: 9) half(num: 12) // 12.0の半分は6.0
- defer statement ( 処理(ブロック)を抜ける前にかならず実行する )
func half(num: Double){ + defer { + print("計算終了") + } guard num>=10 else { return } let halfNum = num/2 print("\(num)の半分は\(halfNum)") } half(num: 25) // 25.0の半分は12.5 // 計算終了 half(num: 9) // 計算終了 <- half(num: 9)は中断されるが、defer文で書いているので実行される half(num: 12) // 12.0の半分は6.0 // 計算終了
- 可変長引数
func sum(numbers: Double...) -> Double { var total: Double = 0.0 for num in numbers { total += num } return total } print(sum(numbers: 4, 5, 6, 7))
- default引数
- func pricel(ninzu: Int, tanaka: Int) -> Int { + func pricel(ninzu: Int = 1, tanaka: Int = 250) -> Int { let result = tanaka * ninzu return result } print(pricel(ninzu: 3, tanaka: 1300))
- Tupleを利用した複数の戻り値
- func pricel(ninzu: Int, tanaka: Int) -> Int { + func pricel(ninzu: Int, tanaka: Int, rate: Double) -> (hoge: Int, fuga: Double) { let result = tanaka * ninzu + let updatedResult = Double(result) * rate - return result + return (result, updatedResult) } - print(pricel(ninzu: 3, tanaka: 1300)) + print(pricel(ninzu: 3, tanaka: 1300, rate: 1.8).hoge)
- 関数の多重定義( 同名の関数でも引数名や引数の個数が違うと別の関数として扱われる。)
func calc(a: Int, b: Int) -> Int { return a+b } func calc (c: Int, d: Int) -> Int { return c*d } func calc(a: Int, b: Int, c: Int) -> Int { return (a+b)*c } print(calc(a: 2, b: 3)) // 5 print(calc(c: 2, d: 3)) // 6 print(calc(a: 2, b: 3, c: 4)) // 20
- 外部引数名
- func pricel(ninzu: Int, tanaka: Int) -> Int { + func pricel(hoge ninzu: Int, fuga tanaka: Int) -> Int { let result = tanaka * ninzu return result } - print(pricel(ninzu: 3, tanaka: 1300)) + print(pricel(hoge: 3, fuga: 1300))
- 引数名なし
- func pricel(hoge ninzu: Int, fuga tanaka: Int) -> Int { + func pricel(_ ninzu: Int, _ tanaka: Int) -> Int { let result = tanaka * ninzu return result } - print(pricel(ninzu: 3, tanaka: 1300)) + print(pricel(3, 1300))
reference from
Swift ざっくり文法 (2)
- Tuple ( タプル )
let product: (String, Int) = ("Swift", 2015) let kingaku = (1000, 80) // 型推論で(Int, Int)に決まる kingaku = (1060, "hoge") // error: cannot call value of non-function type '(Int, Int)'
let data = (1000, 80) let (price, _) = data print(price)
不要な値は、_
で無視できる。
let data = (1000, 80) print(data.0)
indexでaccess
let kingaku = (price: 1000, tax: 80) let seikyuugaku = kingaku.price + kingaku.tax print(seikyuugaku)
ラベル付け
Range
..<
終了値を含まない...
終了値を含む
Bitwise Operators
- 2進数 接頭辞に
0b
16進数 接頭辞に
0x
Bit Shift
- 指定した方向に桁をシフトする演算( 10進数の数値を左を一桁シフトすると値が10倍になるように2進数の値を左へ1桁シフトすると値が2倍になる。 )
- 2進数 接頭辞に
let v: UInt8 = 0b00000101 let v2 = v<<1 print(v, v2) // 5, 10
- Bitwise operation
演算式 | 説明 |
---|---|
a & b | ビット積、各桁を比較し、両方の桁が1ならば1 |
a | b | ビット和、各桁を比較し、どちらかの桁が1ならば1 |
a ^ b | 排他的ビット和、各桁を比較し、片方が1の桁だけ1 |
~a | ビット否定、各桁の1と0を反転 |
16進数#40E0D0 からビット積とビットシフトを使って、RGBを取り出して、0~255 の値に変換し、さらに255 で割って0~1にしてビューの背景色に指定
let RGB: UInt32 = 0x40E0D0 // turquoise(64, 224, 208) let red = (RGB & 0xFF0000) >> 16 // 上位二桁 let green = (RGB & 0x00FF00) >> 16 // 中央二桁 let blue = RGB & 0x0000FF // 下二桁 let R = CGFloat(red)/255 let G = CGFloat(green)/255 let B = CGFloat(blue)/255 view.backgroundColor = UIColor(red: R, green: G, blue: B, alpha: 1)
ビット否定
let v: UInt8 = 0b00001010 let v2 = ~v print(v, v2) //10 245
- if statementでは以下のような書き方が可能
- if ((sugaku>=40) && (eigo>=60) && ((suugaku+eigo)>=120)) { + if sugaku>=40, eigo>=60, (suugaku+eigo)>=120 {
- Switch statement
- swiftのswitch statementは、breakがなくても抜けてくれる。
意図的に処理を次のcase文に渡したい場合は、
fallthrough
キーワードを書く。value binding
let size = (4, 10) switch size { case (0, 0): print("hoge") case (5...10, 5...10): print("bar") case (5...10, let height): // print("height:" + "\(height)") case (let width, 5...10): print("width:" + "\(width)") default: print("foo") }
where で、値の振り分けに条件式を使えるようになる。
let size = (45, 40, 100) switch size { case let (width, height, _) where (width>=60) || (height>=60): print("hoge") case let (_, _, weight) where (weight>=80): print("bar") default: print("foo") }
caseに当てはまらない値があり得る場合には、最後のdefaultは必ず必要だが、caseに当てはまらない値がない場合はdefaultを省略可能
let aPoint = (50, 100) switch aPoint { case (0, 0): print("中心点") case (0, _): print("x軸上の点") case (_, 0): // print("y軸上の点") case (x, y): print("点(\(x), \(y))") }
- 単に処理を任意の回数繰り返したい時( rubyでいうところの、
times
みたいな感じ )
for _ in 1...15 { let num = arc4random_uniform(100) print(num, terminator: ",") }
- for-in でstringから一文字ずつ取り出す
let message = "ありがとう" for char in message { print(char) } // あ // り // が // と // う
- 飛び飛びで繰り返す
for-in stride()
for num in stride(from: 10, to: 30, by: 3) { print(num, terminator: ",") } // 10, 13, 16, 19, 22, 25, 28
- 他の言語で言うところの
do-while
は、swiftだとrepeat-while
- loop ( for-in, while, repeat-while ) には、labelが付けられる
xloop: for x in 0...3 { yloop: for y in 0...3 { if (x<y) { print("------") continue xloop // yloopを中断して、xloopに抜ける } print((x, y)) } }
let vlist:Array = [[4, 2], [5], [9, 8, 10], [6, 8, -9], [4, 2], [9, 3]] outloop: for alist in vlist { inloop: for v in alist { if v<0 { print(alist) break outloop // inloop だけでなく、outloopも中断する。 } } }
- 複数行のString literal ( swift4から )
""" swift4 swift3 swift4 """
- Array
let colors:[String] = ["red", "blue", "green"] let hoge:[Any] = ["ed", "bl", 3]
var numList:Array<Int> = [12, 34, 56, 79, 59]
var resultList:Array<Bool> resultList = [true, false, true, false]
var stringList = ["foo", "bar", "baz"] // stringList は、型推論で[String]に設定されているため、それ以外の型を入れようとするとエラー stringList = [3, 4, 6] // error: cannot convert value of type 'Int' to expected element type 'String'
空のArray
var resultList:Array<Bool> resultList = []
var resultList = [Bool]() var resultList = Array<Double>()
Repeating
var stars = String(repeating: "★", count: 7) // "★★★★★★★" var resultList = Array<Bool>(repeating: true, count: 5) // [true, true, true, true, true]
配列を別の変数に代入すると、変数には配列の参照ではなく、コピー(複製)が作られて入る。
var array1 = [1, 2, 3] let array2 = array1 // ここまではシャローコピー array1[0] = 99 // ここでディープコピー print("array \(array1)") print("array \(array2)")
Copyの種類
- Shallow Copy
- 元の配列の参照をコピーしただけで実際には同じ配列を指した別名の配列を作る
- Deep copy
- 同じ値をもった完全に新しい別の配列を作る
- Lazy copy in Swift
- 配列を一旦Shallow Copyして、配列の要素や値を変更しようとした時点で自動的にDeep copyした新しい配列を作る
- Shallow Copy
Set
- 配列と違ってSetは同じ値を重複して持つことができず、値には順番がない。
let colorSet:Set<String> = ["red", "green", "blue", "green"] print(colorSet) // ["green", "red", "blue"] print(type(of: colorSet)) // Set<String>
Array -> Set, Set -> Array
var colorArray = ["red", "green", "blue", "green"] print(colorArray, type(of: colorArray)) // ["red", "green", "blue", "green"] Array<String> let colorSet = Set(colorArray) colorArray = Array(colorSet) print(colorSet, type(of: colorSet)) // ["blue", "green", "red"] Set<String> print(colorArray, type(of: colorArray)) // ["blue", "green", "red"] Array<String>
- 空のSet
var numSet:Set<Int> = []
- Setに値を追加しても、重複していれば、同じ値は入らない。
var numSet:Set<Int> = [] numSet.insert(3) numSet.insert(5) numSet.insert(7) numSet.insert(9) numSet.insert(5) print(numSet) // [5, 7, 3, 9]
- Closure
let ageArray = [21, 30, 28, 35, 45, 52, 33] let age30to39 = ageArray.filter({(age: Int) -> Bool in return (age>=30)&&(age<40) }) print(age30to39)
- dictionary
- キーは、全てが同じ型で重複しない一意なものでないといけない。
let sizeTable = ["S": 47, "M": 52, "L": 55] let sizeTable:[String:Int] = ["S": 47, "M": 52, "L": 55] let sizeTable:Dictionary<String, Int> = ["S": 47, "M": 52, "L": 55]
空のdictionary
let sizeTable:[String:Int] = [:] let sizeTable = [String:Int]() let sizeTable = Dictionary<String, Int>()
TupleからDictionaryを作る
let a = ("A", 1) let b = ("B", 2) let c = ("C", 3) let abcDic = Dictionary(dictionaryLiteral: a, b, c) print(abcDic)