๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

study iOS๐ŸŽ/์ฃผ์ ‘ Swift - swift ํ…Œ๋งˆ

[Too Swift] ์‹œ์ฆŒ1 1ํ™”. ํด๋กœ์ €๊ฐ€ ๋ˆ„๊ตฐ๋ฐ ? (who's mr. closure?)

Collection Iteration with Closure : Mr. closure์™€ ํ•จ๊ป˜ํ•˜๋Š”, ์ปฌ๋ ‰์…˜ ์ดํ„ฐ๋ ˆ์ด์…˜ 

์ผ๋ จ์˜ ํ”„๋กœ์‹œ์ ธ๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๋Š”, func์ด์™ธ์˜ ๋˜ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์ด ๋˜๋Š” ...
ํŠนํžˆ, ์ปฌ๋ ‰์…˜๋“ค์„ ๋‹ค๋ฃฐ ๋•Œ ํŠนํžˆ ์œ ์šฉํ•œ ...
๋ณ€์ˆ˜์— ํ• ๋‹นํ•ด, ๋‹ค๋ฅธ value๋“ค ์ฒ˜๋Ÿผ "์ฃผ๊ณ  ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š”" ...
๊ทธ ๋ถ„ ...

์ด๋ฆ„ ์—†๋Š” ํ•จ์ˆ˜ ...
Mr. closure๋ฅผ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค.

์ฐธ๊ณ  : Raywenderlich 
"Swift Apprentice
https://store.raywenderlich.com/products/swift-apprentice

 

 

 

Closure Basics ํด๋กœ์ € ์Œฉ๊ธฐ์ดˆ + training

ํด๋กœ์ ธ๋Š” ๋‘˜๋Ÿฌ์‹ผ ํ™˜๊ฒฝ์˜ ๋ณ€์ˆ˜๋‚˜ ์ƒ์ˆ˜๋ฅผ ์ž์‹ ์˜ scope์œผ๋กœ "close over"ํ•  ์ˆ˜ ์žˆ์–ด์„œ, ํด๋กœ์ €๋ผ๋Š” ์ด๋ฆ„์ด ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. ์ด close over vars. and consts. ๋Š” captureํ•œ๋‹ค๊ณ ๋„ ํ•˜๋Š” ๋ฐ ์ถ”ํ›„์— ์ž์„ธํžˆ ์„ค๋ช…ํ•ด๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ์€ ๊ฑ ์žŠ์œผ์„ธ์š” ^^ ์˜์–ด๋กœ๋งŒ ์จ์„œ ์ฃ„์†กํ•ด์š”. ์ง€๋Œ€๋กœ ์„ค๋ช…ํ•˜๋Š” ๋ถ€๋ถ„์—๋Š” ์ˆœ์šฐ๋ฆฌ๋ง๋กœ ์ง€๋Œ€๋กœ ์“ฐ๊ฒ ์Šต๋‹ˆ๋‹ค.

 

 

----> 1). ์–ด๋–ป๊ฒŒ ๋งŒ๋“œ๋‚˜์š”?

var multiplyClosure: (Int, Int) -> Int

์šฐ์„ , ํด๋กœ์ €๋ฅผ ๋‹ด์„ ๋ณ€์ˆ˜๋Š”, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํƒ€์žŽ์„ ๋ช…์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•จ์ˆ˜๋ฅผ ์ฃผ๊ณ  ๋ฐ›์„ ๋•Œ์™€ ๋™์ผํ•˜์ฃ .

 

 

----> 2). ๊ฐ’์€ ์–ด๋–ป๊ฒŒ assign ํ•˜๋Š” ๋ฐ์š”?

---- ----> 1. ํ‘œ์ค€ํ˜•

// ํƒ€์žŽ ๋ช…์‹œ ์—†์„ ๋•Œ,ํƒ€์žŽ ์ถ”๋ก  ํ•˜๋Š” ๊ฒƒ๋„ ์ž˜ ๋ณด์„ธ์š” ^^
var multiplyClosure = { (a: Int, b: Int) -> Int in
	return a*b
}

// ์‚ฌ์šฉ
let result = multiplyClosure(4, 2)

  ํ•จ์ˆ˜ ์„ ์–ธํ•  ๋•Œ๋ž‘, ์ข€ ๋‹ค๋ฅธ ์ ์ด๋ผ๋ฉด ์ž…๋ ฅ์— ๋Œ€ํ•ด ๋ช…์‹œํ•  ๋•Œ, _ a: Int, by b: Int ์™€ ๊ฐ™์ด ํ•จ์ˆ˜์˜ ์ž…๋ ฅ์—  external argument label ์™ธ๋ถ€์—์„œ ์ธ์ž๋ฅผ ์ง€์นญํ•˜๋Š” ์™ธ๋ถ€ ๋ผ๋ฒจ ๋”ฐ์œ„๋Š” ์—†์Šต๋‹ˆ๋‹ค. ํด๋กœ์ € ์ž์ฒด๊ฐ€ ๊ฐ„ํŽธํ•œ ํ•จ์ˆ˜ ์ „๋‹ฌ์ด ๋ชฉ์ ์ด๋‹ˆ ์ตœ๋Œ€ํ•œ ๊ฐ€๋ณ๊ฒŒ ํ•ด์•ผ์ฅฌ. ๊ทธ๊ฑด ์Šค์œ„ํ”„ํŠธ ์–ธ์–ด ๋””์ž์ด๋„ˆ ๋งด์ž…๋‹ˆ๋‹ค. ์ €ํฌ๋Š” ๊ทธ์ € ๋”ฐ๋ฅผ๋ฟ.

 

  ์ด์šฉ ๋ฐฉ๋ฒ•์€ ๊ทธ๋ƒฅ ํ•จ์ˆ˜์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ํด๋กœ์ ธ๋ช…(์ž…๋ ฅ1, ์ž…๋ ฅ2, ... ํ•„์š”ํ•œ ๋งจํผ)

 

 

----> 3). Shorthand syntax ์ถ•์•ฝ๋œ ํด๋กœ์ € ๋ฌธ๋ฒ•๋“ค

  ์• ํ”Œ ๋ฌธ์„œ๋ณผ ๋•Œ ์•„์‹œ๊ฒ ์ง€๋งŒ,  ๋‹ค๋ฅธ ์–ธ์–ด๋ฅผ ์“ฐ๋‹ค ์Šค์œ„ํ”„ํŠธ ๋„ํ๋จผํŠธ๋ฅผ ๋ณด๋ฉด, ์• ํ”Œ ํ…์…˜์œผ๋กœ ๋ฐ”๊พธ๊ณ  ์ค„์—ฌ๋†“์€ ์‹ ํƒ์Šค์— ๋ญ”๊ฐ€ ์‹ฌ์˜คํ•ด๋ณด์ด๋Š” ์ขŒ์ ˆ๊ฐ์„ ๋ฐ›๊ณคํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ์—, syntax๊ฐ€ ๋ญ๊ฐ€ ์ค‘์š”ํ•ด? ๊ฑ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ์ค‘์š”ํ•˜์ง€ --> ๋ฏธ๋ž˜์˜ ๋‚ด ๋ˆˆ๊ณผ ๋‡Œ๋ฅผ ์œ„ํ•ด ์‹ ํƒ์Šค ์ง€์‹์„ ์„ ๋ฌผํ• ๊ฒŒ ๋ผ๋Š” ๋งˆ์ธ๋“œ๋กœ ๊ณต๋ถ€ํ•ด๋ณด๋Š” ๊ฒŒ ๋‚˜์˜์ง€ ์•Š์•„๋ณด์ž…๋‹ˆ๋‹ค.    AI AI AI !! ์•„๋‹ˆ๊ณ   syntax, syntax, syntax !! 

์•„๋ž˜์™€ ๊ฐ™์ด ์‹ ํƒ์Šค๋ฅผ ๋งŒ๋“  ๋ฐ๋Š” ๋ณ„๋‹ค๋ฅธ ์ด์œ ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค -> ์• ํ”Œ์Šค๋Ÿฝ๊ฒŒ, ๊ฐ™์€ ๋ช…๋ น์„ ์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ์ตœ๋Œ€ํ•œ ์ ๊ฒŒ ํƒ€์ดํ•‘ํ•˜๋ฉด์„œ๋„ ๋ช…๋ฃŒํ•˜๊ฒŒ ๋งŒ๋“ค ๊นŒํ•˜๋‹ค๊ฐ€ ๋งŒ๋“ค์–ด์ง„ ๊ฒƒ์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

1).  ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฆฌ์ŠคํŠธ: ์œ ์ง€, ๋ฆฌํ„ด ํƒ€์žŽ: ์œ ์ง€, inํ‚ค์›Œ๋“œ: ์œ ์ง€, returnํ‚ค์›Œ๋“œ: ์ƒ๋žต : ๋ฆฌํ„ดํ•  ํ•ญ๋ชฉ์„ ํ•œ ์ค„ ์ด๋‚ด์— ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด, ๊ทธ๊ฒƒ๋งŒ ์จ๋„ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์•Œ์•„์„œ ์ปดํŒŒ์ผ ํ•ด์ค๋‹ˆ๋‹ค.

multiplyClosure = { (a: Int, b: Int) -> Int in
	a * b
}

 

2).  ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฆฌ์ŠคํŠธ: ์ธํ„ฐ๋„ ๋ผ๋ฒจ๋งŒ ์œ ์ง€, ๋ฆฌํ„ด ํƒ€์žŽ: ์ƒ๋žต, inํ‚ค์›Œ๋“œ: ์œ ์ง€, returnํ‚ค์›Œ๋“œ: ์ƒ๋žต 

/ * ์ด๋ฏธ ํƒ€์žŽ ์™ธ์ ์œผ๋กœ ๋ช…์‹œํ•œ ๊ฒฝ์šฐ๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ
var multiplyClosure = { (a: Int, b: Int) -> Int in
	return a*b
}
*/

// ๊ฐ„๋žตํ•˜๊ฒŒ ์žฌ์ง€์ • ํ•ด์ฃผ๊ธฐ (์ด๋ฆ„1, ์ด๋ฆ„2) in ์ด๋ฆ„1 * ์ด๋ฆ„2
multiplyClosure = { (a, b) in
	a * b
}

 

3). ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฆฌ์ŠคํŠธ: ์ƒ๋žต, ๋ฆฌํ„ด ํƒ€์žŽ: ์ƒ๋žต, inํ‚ค์›Œ๋“œ: ์ƒ๋žต, returnํ‚ค์›Œ๋“œ: ์ƒ๋žต  : + ์ž…๋ ฅ ์ธ์ž๋ฅผ $0, $1๋กœ ์ง€์นญ

์ด ์‹ ํƒ์Šค๋„ ์ž์ฃผ ์“ฐ์ด๋‹ˆ !! ์‹ ํƒ์Šค ! ์‹ ํƒ์Šค! ์‹ ํƒ์Šค! ํ•œ ๋ฒˆ ํƒ€์ดํ•‘ ํ•ด๋ณด์‹œ๋ฉด์„œ ์ตํžˆ์‹œ๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

// pass function as a parametre
func operateOnNumbers(_ a: Int, _ b: Int, operation: (Int, Int) -> Int ) -> Int {
    
    let result = operation(a, b)
    print(result)
    return result
    
}

// ํด๋กœ์ ธ๋ฅผ ์ธ์ž๋กœ ์ „๋‹ฌ
operateOnNumbers(4, 2, operation: { $0 + $1 })

์œ„์˜ ํ•จ์ˆ˜๋Š” operation ์ธ์ž๋กœ (Int, Int) -> Int ๋ผ๋Š” ํ•จ์ˆ˜ ๋˜๋Š” ํด๋กœ์ €(์ด๋ฆ„ ์—†๋Š” ํ•จ์ˆ˜)๋ฅผ ๋ฐ›์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ƒํ™ฉ์—, ํด๋กœ์ €๋ฅผ ์ „๋‹ฌํ•ด์ฃผ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์œ„์—์„œ๋„ ์ฒซ ๋ฒˆ์งธ ์ธ์ž์™€, ๋‘ ๋ฒˆ์งธ ์ธ์ž๋ฅผ ๋”ํ•œ ๊ฐ’์„ ๋ฆฌํ„ดํ•œ๋‹ค๋Š” ํด๋กœ์ ธ๋ฅผ ์ธ์ž๋กœ ์ „๋‹ฌํ•˜์˜€๊ณ , ์ €ํฌ๊ฐ€ ์ด๋ฏธ ์œ„์—์„œ ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•  ๋•Œ, ํƒ€์žŽ์— ๋Œ€ํ•ด์„œ๋Š” ์ด๋Ÿฐ ์ด๋Ÿฐ ์ธํ’‹์ด ๋“ค์–ด์˜ฌ ๊ฒƒ์ด๋‹ค๋ผ๋Š” ๊ฒƒ์„ ๋ช…์‹œํ•ด ๋‘์—ˆ๊ธฐ ๋•Œ๋ฌธ์—, operation์ธ์ž๋กœ,

ํƒ€์žŽ์ด ๋ช…์‹œ๋˜์ง€ ์•Š์€

params list, in keyword, return ๋“ฑ์ด ์ƒ๋žต๋œ

ํด๋กœ์ €๋ฅผ ์ „๋‹ฌํ•ด๋„, ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ํ•จ์ˆ˜๋ฅผ ์ถ”๋ก ํ•ด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Trailing Closure Syntax

์Šค์œ„ํ”„ํŠธ๋ฅผ ๋ณด๋ฉด, ๋งค์šฐ ์ด์ƒํ•œ ํ˜•์‹์˜ ํ•จ์ˆ˜ ํ˜ธ์ถœ์„ ๋ณผ ์ˆ˜ ์žˆ๋Š”๋ฐ,

์—ฌ๊ธฐ์„œ "trailing closure syntax"์— ๋Œ€ํ•ด์„œ ์ด์•ผ๊ธฐ ํ•ด๋ณด๋ ค ํ•œ๋‹ค. 

 

์œ„์—์„œ๋Š” " operation: ์ด๋ผ๋Š” ์ธ์ž์— { $0 + $1 } ๋ผ๋Š” ํด๋กœ์ ธ๋ฅผ ์ „๋‹ฌ"ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ํด๋กœ์ ธ๋ฅผ ํ˜ธ์ถœํ–ˆ๋Š”๋ฐ,

์Šค์œ„ํ”„ํŠธ๋Š” ๋งŒ์•ฝ, ์ธ์ž ์ค‘ ๋งˆ์ง€๋ง‰์ด ํ•จ์ˆ˜๋ฅผ ๋ฐ›๋Š” ๊ฒฝ์šฐ์—๋Š”, ๋” ๋” ๋” ๊ฐ„๋‹จํ•œ ์‹ ํƒ์Šค๋ฅผ ์จ์„œ, ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค.

operateOnNumbers(4,2){
	$0 + $1
}

* ๋งŒ์•ฝ, ์–ด๋–ค ํ•จ์ˆ˜์˜ ๋งˆ์ง€๋ง‰ ์ธ์ž๊ฐ€ ํ•จ์ˆ˜๋ผ๋ฉด, 1). ์ธ์ž ๋ผ๋ฒจ์„ ์ƒ๋žตํ•˜๊ณ , ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์•„์˜ˆ 2). (   ) ๋ฐ–์— ํด๋กœ์ ธ๋ฅผ ํ›„ํ–‰ํ•˜๋Š”trailing ๋ฐฉ์‹์œผ๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งค์šฐ ์ž‘์€ (  ) parenthesis ์•ˆ์— ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค, ์•„์˜ˆ ๊ธธ์–ด์งˆ ์ˆ˜ ์žˆ๋Š” ํด๋กœ์ ธ๊ฐ€ ๋“ค์–ด๊ฐ€๋Š” ๊ฒฝ์šฐ๋Š” ( )์— trailing(ํ›„ํ–‰ํ•˜๋Š”) ์ „๋‹ฌ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค.  

empty params list and empty return 

let voidClosure2: () -> Void = {
	print("Swift is so awesome")
}

// also possible
let voidClosure3: () -> () = {
	print("Swift is so awsome")
}

๋งŒ์•ฝ, ์Šค์œ„ํ”„ํŠธ๊ฐ€ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ํ•„์š” ์—†๊ฑฐ๋‚˜, ์•„๋ฌด ๊ฒƒ๋„ ๋ฆฌํ„ดํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์œ„์™€ ๊ฐ™์€ ๋‘ ๊ฐ€์ง€ ์˜ต์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ•จ์ˆ˜์‹ ํ‘œํ˜„์„

ํƒ€์žŽ์— ๋ช…์‹œํ•ด์ฃผ์–ด์•ผํ•˜๋Š”๋ฐ, ( ) -> Void ๋˜๋Š” -> ( )์™€ ๊ฐ™์ด ๋ช…์‹œํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

 

----> 4). Closure Capture : < capture variables from enclosing scope >

  ํด๋กœ์ €๋Š” ๊ทธ๊ฒƒ์„ ๋‘˜๋Ÿฌ์‹ผ ํ™˜๊ฒฝ์— ์žˆ๋Š” entities(๋ณ€์ˆ˜, ์ƒ์ˆ˜)๋ฅผ ์บก์ณํ•ด์„œ, ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, ํด๋กœ์ €๊ฐ€ ์ •์˜๋œ ๊ฒƒ์„ ๋‘˜๋Ÿฌ์Œ“์€ ์™ธ๋ถ€ ํ™˜๊ฒฝ์˜ ๋ณ€์ˆ˜๋‚˜ ์ƒ์ˆ˜์˜ scope์€ ํด๋กœ์ € ๋‚ด๋ถ€๋„ ํฌํ•จ๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

func countingClosure() -> () -> Int {
    
    // ๋กœ์ปฌ ๋ณ€์ˆ˜
    var counter = 0
    
    // ํ•จ์ˆ˜์˜ ๋กœ์ปฌ ๋ณ€์ˆ˜๋ฅผ ์บก์ณํ•˜๋Š” ํด๋กœ์ ธ, ๊ทธ ๊ฒƒ์— +1์„ ํ•˜๊ณ  ๋ฆฌํ„ด ํ•œ๋‹ค
    let incrementCounter: ( ) -> Int = {
        counter += 1
        return counter // ์œ„์˜ ํ”„๋กœ์‹œ์ ธ๋ฅผ ์ง„ํ–‰ํ•˜๊ณ  counter๋ฅผ ๋ฆฌํ„ดํ•œ๋‹ค.
    }
    
    // ๊ทธ๋ ‡๊ฒŒ ์บก์ณํ•ด์„œ, +1์„ํ•˜๊ณ  ๋ฆฌํ„ดํ•ด์ค€๋‹ค๋Š” ์ธํฌ๋ฆฌ๋จผํŠธ ์นด์šดํ„ฐ "ํด๋กœ์ ธ๋ฅผ ๋ฆฌํ„ด"
    return incrementCounter
}

// 
counter1 = countingClosure()
counter2 = countingClosure()
counter1( ) // 1
counter1( ) // 2
counter2( ) // 1
counter2( ) // 2

 surrounding environment's entities๋ฅผ captureํ•œ๋‹ค๋Š” ๊ฒƒ์€ ๋ฌด์Šจ ๋œป์ผ๊นŒ์š”? ์บก์ณ๋ผ๋Š” ๊ฒŒ ์–ด๋–ค ๊ฒƒ์„ ํฌ์ฐฉํ•ด์„œ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋‹ค๋Š” ๋œป์ด์ฃ ? ์ €ํฌ๋„ ์œ ํˆฌ๋ธŒ ๋™์˜์ƒ์˜ ํ•œ ์ˆœ๊ฐ„์„ ์บก์ณํ•ด์„œ ๊ฐ€์ง€๊ณ  ์žˆ๊ฒŒ๋ฉ๋‹ˆ๋‹ค. ํด๋กœ์ ธ์˜ ์บก์ณ๋„ ๋น„์Šทํ•œ ๊ฐœ๋…์œผ๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

 

 ์œ„์—์„œ ๋ณด๋ฉด, countingClosureํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด, ๋กœ์ปฌ ๋ณ€์ˆ˜์ธ counter๊ฐ€ ์ƒ์„ฑ๋˜๊ณ , incrementCounter๋ผ๋Š” ํด๋กœ์ ธ๋Š” ๊ทธ ๋•Œ ์ƒ์„ฑ๋œ ๋กœ์ปฌ ๋ณ€์ˆ˜๋ฅผ ์บก์ณํ•ด๋†“์Šต๋‹ˆ๋‹ค. ์ด๋•Œ ์ด ํด๋กœ์ ธ๋Š” ์ด ๋กœ์ปฌ ๋ณ€์ˆ˜๋ฅผ "๋ ˆํผ๋Ÿฐ์Šค" ๋ณ€์ˆ˜ ํ™” ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ๊ฐ’์„ ํž™ ๋ฉ”๋ชจ๋ฆฌ๋กœ ์˜ฎ๊ฒจ, ๊ทธ๊ฒƒ์— ๋Œ€ํ•œ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ, ๊ทธ๊ฒƒ์„ counter๋ผ๊ณ  ๋ถ€๋ฅด๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ฒŒ counter๋ผ๋Š” ํž™ ๋ฉ”๋ชจ๋ฆฌ ์ƒ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์บก์ณํ•ด๋‚ธ ํด๋กœ์ ธ๊ฐ€ ๋ฆฌํ„ด๋˜๋Š” ๋ฐ, ์ด๋•Œ ๋งŒ์•ฝ counter๊ฐ€ ํ•จ์ˆ˜์˜ ๋กœ์ปฌ ๋ณ€์ˆ˜์˜€์œผ๋ฉด, save๋˜์ง€ ์•Š์•„ ์œ ์ง€๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, ํด๋กœ์ ธ๋Š” ๊ทธ๊ฒƒ์„ ํž™์— ์ €์žฅํ•ด counter๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉด, ํด๋กœ์ ธ๊ฐ€ ํ•ด๋‹น ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ง€์›Œ์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

 

  ์ฒซ ๋ฒˆ์งธ ์นด์šดํŒ…ํด๋กœ์ ธ( )๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด, ๊ทธ๋•Œ ์นด์šดํ„ฐ ๋ณ€์ˆ˜๋ฅผ ์บก์ณํ•˜์—ฌ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ํด๋กœ์ ธ์ธ counter1 ์ด ์ƒ๊น๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‘๋ฒˆ์งธ ํ˜ธ์ถœํ•  ๋•Œ๋Š” ๋˜ ๊ทธ๋•Œ ์ƒ์„ฑ๋˜์–ด ํž™์— ์ €์žฅ๋œ ๋ ˆํผ๋Ÿฐ์Šค counter๊ฐ€ ์ƒ๊น๋‹ˆ๋‹ค. ๊ฐ ํด๋กœ์ € ๋‚ด์—์„œ๋Š” ํž™ ๋ฉ”๋ชจ๋ฆฌ ์ƒ์˜ ๋‹ค๋ฅธ ์œ„์น˜์— ๋Œ€ํ•ด ๊ฐ™์€ ์ด๋ฆ„์˜ ๋ ˆํผ๋Ÿฐ์Šค ๋ณ€์ˆ˜๋ฅผ ๊ฐ€์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. 

 

 ๊ฐ๊ฐ ์„œ๋กœ ๋‹ค๋ฅธ ์œ„์น˜์˜ ํž™ ๋ฉ”๋ชจ๋ฆฌ์ƒ ๋ฐ์ดํ„ฐ, ๋™๋ช…์˜ ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ๊ฐ +1 +1 ํ•˜๋ฉด์„œ ๋ฆฌํ„ดํ•ด์ฃผ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. 

์บก์ณ๋ผ๋Š” ๊ฒƒ์˜ ๊ฐœ๋…์ด ์™€๋‹ฟ์ง€ ์•Š์•„ ์ข‹์€ ๋ธ”๋กœ๊ทธ ๊ธ€์„ ์ฐธ๊ณ ํ•˜์—ฌ ์ดํ•ดํ•˜๊ฒŒ๋˜์–ด, ์ด ๊ธ€์„ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ถœ์ฒ˜ :

https://velog.io/@kimdo2297/%ED%81%B4%EB%A1%9C%EC%A0%B8-%EC%BA%A1%EC%B3%90%EC%97%90-%EB%8C%80%ED%95%B4%EC%84%9C-about-closure-capture 

 

ํด๋กœ์ € ์บก์ณ์— ๋Œ€ํ•ด์„œ (about closure capture)

์ถœ์ฒ˜ :

velog.io

>>> Human is pattern making pro !!

>>> ์—ฐ์Šตํ•ด ๋ด…์‹œ๋‹ค : ์ด๋ฒˆ์—๋Š” ํด๋กœ์ €๊ฐ€, ์ž์‹ ์ด ์ •์˜๋˜๊ณ  ์žˆ๋Š” ํ•จ์ˆ˜ ํ”„๋กœ์‹œ์ € ๋‚ด์—์„œ,

- ํŒŒ๋ผ๋ฏธํ„ฐ

- ์ง€์—ญ๋ณ€์ˆ˜

๋ชจ๋‘๋ฅผ ์บก์ณํ•ด์„œ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.

func makeIncrementer(forIncrement amount: Int) -> () -> Int {
    
    var runningTotal = 0 // local ๋ณ€์ˆ˜๋ฅผ ๋งค๊น€ => ์บก์ณํ•ด์„œ => ํž™์œผ๋กœ ์˜ฎ๊ฒจ์„œ ํ•ด๋‹น ์ง€์นญ์„ ์œ ์ง€ํ•˜๋Š” ํด๋กœ์ €
    
    let incrementer = { ( ) -> Int in
        runningTotal += amount // ํŒŒ๋ผ๋ฏธํ„ฐ์ธ amount ์บก์ณํ•ด์„œ ๋ ˆํผ๋Ÿฐ์Šค ์œ ์ง€, runningTotal๋„ ์ฐฐ์นต!!
        return runningTotal
    }
    
    return incrementer
}

let incrementer5 = makeIncrementer(forIncrement: 5)
let incrementer10 = makeIncrementer(forIncrement: 10)

incrementer5( ) // 5
incrementer10( ) // 10

incrementer5( ) // 10
incrementer10( ) // 20

incrementer5( ) // 15
incrementer10( ) // 30

 

 

----> 5). Easy collections control using: Closure

์ด์ œ, ํด๋กœ์ €๋ฅผ ๋ฐฐ์šด ๊ฒƒ์„ ๋ˆ„๋ ค๋ด…์‹œ๋‹ค. ๊ฐ€์žฅ ์œ ์šฉํ•œ ๋ฐฉํ–ฅ์€ ๋ฐ”๋กœ, ์ปฌ๋ ‰์…˜์„ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ๊ฐ€์ง€๊ณ  ๋†€๊ธฐ. Too Swift !!

 

  ํด๋กœ์ ธ์˜ ์‹ ํƒ์Šค๋ฅผ ์•Œ๋ฉด, ์Šค์œ„ํ”„ํŠธ์˜ ์ปฌ๋ ‰์…˜ ํƒ€์žŽ๋“ค์„ ๋งค์šฐ ๊ฐ„๋‹จํ•œ ํ˜•ํƒœ๋กœ ํ†ต์ œํ•  ์ˆ˜ ์žˆ๋Š”, ์ปฌ๋ ‰์…˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๊ฐ–์ถ”์–ด์ ธ ์žˆ์Šต๋‹ˆ๋‹ค. "ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ"์„ ์ง€ํ–ฅํ•˜๋Š” ์Šค์œ„ํ”„ํŠธ์—์„œ๋Š”, ์ปฌ๋ ‰์…˜ ์˜คํผ๋ ˆ์ด์…˜์— ์ธ์ž๋กœ์„œ "ํด๋กœ์ ธ"๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ž‘๋™ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๊ณ , ์ด๋•Œ closure trailing syntax๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, ์ด๋Ÿฌํ•œ ๊ฒƒ๋“ค์ด ์‹ ํƒ์Šค์ ์œผ๋กœ ๋งค์šฐ ๊ฐ„๋‹จํ•˜๊ฒŒ ํ•ด๊ฒฐ ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. 

1). ์ •๋ ฌ ๋ฌธ์ œ ํ•ด๊ฒฐ

let names = [ "zebra", "boeing", "ace", "create", "eastern"]

// ์ฒซ ๋ฒˆ์งธ ์•„๊ทœ๋จผํŠธ๊ฐ€ ๋” ์ปค์•ผํ•ด
1).
names.sorted{
    $0.count > $1.count 
} 

// ์ฒซ ๋ฒˆ์งธ ์•„๊ทœ๋จผํŠธ๊ฐ€ ๋” ์ž‘์•„์•ผํ•ด
2).
names.sorted{
    $0.count < $1.count
}

// ๋„ํ๋จผํŠธ ์ฐธ๊ณ 
// ์ธ์ž ์„ค๋ช…
// areInIncreasingOrder : 	
// A predicate that returns true if its first argument 
// should be ordered before its second argument; otherwise, false.

1 ๋ฒˆ์งธ ์•„์›ƒํ’‹

 

2๋ฒˆ ์งธ ์•„์›ƒํ’‹

์ „์ œ ์กฐ๊ฑด : ํ•จ์ˆ˜๋‚˜ ํด๋กœ์ €๋ฅผ ์ „๋‹ฌํ•ด๋ผ. ๋งŒ์•ฝ ์ฐธ์ผ ๊ฒฝ์šฐ, ์ฒซ๋ฒˆ์งธ ์ธ์ž๊ฐ€ ๋‘๋ฒˆ์งธ ์ธ์ž์˜ ์•ž์œผ๋กœ ๊ฐ€์•ผํ•˜๋Š” ํ•จ์ˆ˜. ์ฆ‰ ์ •๋ ฌ์˜ ์กฐ๊ฑด์ธ ( ์ •, ์ • ) -> ๋ถˆ ํด๋กœ์ €

 

2). Iterative operation : ์ปฌ๋ ‰์…˜์˜ ๊ฐ ์š”์†Œ๋ฅผ ์ดํ„ฐ๋ ˆ์ด์…˜ํ•˜๋ฉด์„œ, ํด๋กœ์ €์— ์ œ์‹œํ•œ ํ”„๋กœ์‹œ์ ธ๋ฅผ ์‹คํ–‰

 

      1). ์ดํ„ฐ๋ ˆ์ด์…˜ ํ•˜๋ฉฐ ๊ฐ ์š”์†Œ์— ๋Œ€ํ•ด ํ”„๋กœ์‹œ์ ธ ์ˆ˜ํ–‰ : forEach

let values = [1, 2, 3, 4, 5, 6, 8, 9]
values.forEach{
    print("\($0): \($0*$0)")
}

// ์ปฌ๋ ‰์…˜์˜ ๊ฐ ์š”์†Œ๋ฅผ ์ดํ„ฐ๋ ˆ์ด์…˜ ํ•˜๋ฉฐ, ๊ฐ ์š”์†Œ์— ๋Œ€ํ•ด ๋‹ค์Œ์„ ์‹คํ–‰

 

      2). ํ•„ํ„ฐ๋ง : ๊ฐ ์š”์†Œ์— ๋ถˆ๋ฆฐ ํ…Œ์ŠคํŠธ ํ•˜์—ฌ ํ•„ํ„ฐ๋งํ•˜์—ฌ true์ธ ๊ฒƒ๋งŒ ๋ฆฌํ„ด

var prices = [ 1.5, 10, 4.99, 2.30, 8.19 ]
let largePrices = prices.filter{
    $0 > 5
}

// original : ๋ฉ”์†Œ๋“œ๊ฐ€ ์ ์šฉ๋˜๋Š” ์–ด๋ ˆ์ด์˜ ๊ฐ’๋“ค์˜ ํƒ€์žŽ Double, -> [Double]
func filter( _ isIncluded: (Element) -> Bool ) -> [ Element ]

let sucky = ["hi", "hilary", "dylan", "friendly", "dude"]

sucky.filter{
    $0.count > 4
}

.filter( ) ํ•จ์ˆ˜๋Š” ๋„ํ๋จผํŠธ ์ƒ

์ปฌ๋ ‰์…˜ ๋ฐ์ดํ„ฐ ํƒ€์žŽ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„ -> ๋ถˆ๋ฆฌ์–ธ ๊ฐ’์„ ๊ณ„์‚ฐํ•˜๋Š” ํด๋กœ์ ธ๋‚˜ ํ•จ์ˆ˜๋ฅผ ๋ฐ›์•„, ์ปฌ๋ ‰์…˜ ๋ฐ์ดํ„ฐ ํƒ€์žŽ์— ํ•ด๋‹นํ•˜๋Š” ๊ฐ’์„ ๋‚ด์–ด๋†“๋Š”, 

ํด๋กœ์ ธ์˜ ๋ฆฌํ„ด๊ฐ’์ด ํŠธ๋ฃจ์ธ ์š”์†Œ๋“ค๋งŒ ๊ฑธ๋Ÿฌ๋‚ด๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.

 

    3). ํ•„ํ„ฐ๋ง : ์˜ค์ง ์ฒซ๋ฒˆ์งธ ์š”์†Œ

print( prices.first{
    $0 > 5
} ?? 0 )



let sucky = ["hi", "hilary", "dylan", "friendly", "dude"]
sucky.filter{
    $0.count > 12
}
var result: String
let over10 = sucky.first(where: {$0.count > 10}) ?? "no such member"
over10

.first์˜ ๊ฒฝ์šฐ ๋นˆ์–ด๋ ˆ์ด๋ฅผ ๋ฆฌํ„ดํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ์š”์†Œ๋ฅผ ๋ฆฌํ„ดํ•˜๋Š” ๊ฒƒ์ธ๋ฐ, ๊ฐ’์ด ์กด์žฌํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ์˜ต์…”๋„๋กœ ๋ฆฌํ„ดํ•œ๋‹ค.

 ์œ„์˜ ํ•จ์ˆ˜๋ฅผ ๋ณด๋ฉด, predicate๋ผ๋Š” ํŒจ๋Ÿฌ๋ฏธํ„ฐ๋ฅผ where๋ผ๋Š” ์•„๊ทœ๋จผํŠธ ๋ผ๋ฒจ๋กœ ๋ฐ›๊ณ ์žˆ๋Š”๋ฐ, ํŒจ๋Ÿฌ๋ฏธํ„ฐ๋Š” ํด๋กœ์ ธ๋กœ ๋ฐ›๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”๋ธ”์„ ๋ฐ›์•„ ๋ถˆ๋ฆฌ์–ธ ๊ฐ’์„ ๋˜์ ธ์ฃผ๋Š” ํ•จ์ˆ˜ ๋˜๋Š” ํด๋กœ์ €๋‚ด์š”. ๊ทธ๋ฆฌ๊ณ  ์ด ํ•จ์ˆ˜๋Š” ์ „์ฒด์ ์œผ๋กœ๋Š” -> < nil์ด๋‚˜ Double >์„ ๋ฆฌํ„ดํ•ฉ๋‹ˆ๋‹ค. ์˜ต์…”๋„ ๋ฐ”์ธ๋”ฉ์ด๋‚˜ ๋‹ ์ฝ”์–ผ๋ฆฌ์‹ฑ์„ ์ด์šฉํ•˜์—ฌ ๋ฐ›์œผ๋ฉด ๋˜๊ฒ ์ฃ .

 

    4). ์ปฌ๋ ‰์…˜.map : ์ปฌ๋ ‰์…˜์˜ ๊ฐ’๋“ค์„ ์ผ๊ด„์ ์œผ๋กœ ํŠน์ • ์—ฐ์‚ฐ์„ ์ ์šฉํ•˜๊ฑฐ๋‚˜, ํ˜•์„ ๋ณ€ํ™˜ํ•  ๋•Œ ( .compacetMap ์œ ์šฉ ) 

 

          1). ์ปฌ๋ ‰์…˜์— ์ผ๊ด„์ ์šฉ map{ $0 * 0.9 }

          2). ์ปฌ๋ ‰์…˜ ์ผ๊ด„์  ํƒ€์ž… ์ปจ๋ฒ„์ ผ ex). map{ Int($0) ?? 0 } : but, have to deal with nil

          3). nil์—†์ด ๊น”๋”ํ•˜๊ฒŒ ์ปจ๋ฒ„์ ผ .compactMap

//
let salesPrices = prices.map{
    $0*0.9
}

//
let userInput = ["0", "11", "haha", "42"]
let number1 = userInput.map{
    Int($0) ?? 0 // ํŒŒ์‹ฑ์ด ์•ˆ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ๋‹ ์ฝ”์–ผ๋ฆฌ์‹ฑ
}

number1

//
userInput.compactMap{
    Int( $0 )
}
// [0, 11, 42]

 

    5). ์ปฌ๋ ‰์…˜.reduce : input์œผ๋กœ starting value, closure๋ฅผ ๋ฐ›๋Š”๋‹ค. :

 

         1. $1์€ ์ดํ„ฐ๋ ˆ์ด์…˜ ํ•˜๋ฉฐ ๊ฐ ์š”์†Œ๊ฐ€ ๋“ค์–ด๊ฐ€๊ณ ,

         2. $0์€ current state : ์ฆ‰ ์ปฌ๋ ‰์…˜์„ ์š”์•ฝํ•œ ํ˜„์žฌ ์ƒํƒœ๊ฐ€ ๋˜๋ฉฐ, ์ฒซ ์ธ์ž๊ฐ€ ์ฒ˜์Œ์— ๊ทธ ๊ฐ’์œผ๋กœ ์ดˆ๊ธฐํ™” ๋ฉ๋‹ˆ๋‹ค.

         3. ๊ณ„์† ํ•ด์„œ ํด๋กœ์ ธ์˜ ๊ฒฐ๊ณผ๊ฐ€ ๋‹ค์‹œ $0์œผ๋กœ ๋‹ค์‹œ ๋“ค์–ด๊ฐ€๊ณ , ๋‹ค์Œ ์š”์†Œ์™€ ํด๋กœ์ € ์•ˆ์˜ ์—ฐ์‚ฐ์ด ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค.

let sum = prices.reduce( 0 ){
	$0 + $1
}

// 0๊ณผ ํด๋กœ์ ธ๋ฅผ ๋ฐ›์•˜๋„ค์š”.
// ํŠน์ง•์€ : ์ฒซ ๋ฒˆ์งธ ์ž…๋ ฅ์œผ๋กœ ๋“ค์–ด๊ฐ„ 0์ด ์ดˆ๊ธฐ $0 : current value์˜ ๊ฐ’์ด ๋˜๊ณ 
// $1 : ์ปฌ๋ ‰์…˜ ๊ฐ ์š”์†Œ์™€ +๊ฐ€ ์ ์šฉ๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

" ํด๋กœ์ ธ์™€ ์ปฌ๋ ‰์…˜ ๋ฉ”์†Œ๋“œ๋ฅผ ์ด์šฉํ•ด์„œ, ๋ช‡ ์•ˆ๋˜๋Š” ์ค„๋กœ, ์ปฌ๋ ‰์…˜์œผ๋กœ ๋ถ€ํ„ฐ ๊ฝค ๋ณต์žกํ•œ ์˜๋ฏธ์žˆ๋Š” ๊ฐ’์„ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

let stock = [1.5: 5, 10: 2, 4.99: 20, 2.30 : 5, 8.19: 30]
let stockSum = stock.reduce(0){
    $0 + $1.key * Double($1.value)
}

//384.5

// ์ปฌ๋ ‰์…˜์ธ ์‚ฌ์ „์— ์ ์šฉํ•˜๋Š” ๋ฆฌ๋“€์Šค๋Š”,
// 0๊ณผ ํด๋กœ์ ธ๋ฅผ ์ž…๋ ฅ์œผ๋กœ ๋ฐ›๊ณ ์žˆ๊ณ 
// ๊ทธ ํด๋กœ์ ธ๋Š”, ๋”๋ธ”๊ฐ’ ํ•˜๋‚˜์™€ ํŠœํ”Œ์„ ์ธํ’‹์œผ๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค.
// ๋ฐ›์€ ํŠœํ”Œ์—์„œ key๋ผ๋Š” ๊ฐ’๊ณผ value๋ผ๋Š” ๊ฐ’์„ ๋”๋ธ”๋กœ ๋ณ€ํ™˜ํ•  ๊ฑธ ๊ณฑํ•˜๊ณ 
// ๋”ํ•˜์—ฌ "ํ˜„์žฌ ์ƒํƒœ๊ฐ’"์„ ๋งŒ๋“ค๋ฉฐ
// ์ด๊ฒƒ์€ ๋‹ค์Œ ์ดํ„ฐ๋ ˆ์ด์…˜ ์‹œ์— ๋‹ค์‹œ $0 ๊ฐ’์œผ๋กœ ์ง‘์–ด ๋„ฃ์Šต๋‹ˆ๋‹ค.

 

         7). ์‚ฌ์ „์ž๋ฃŒ๊ตฌ์กฐ.reduce( into: , _: closure )

 

์˜ˆ๋ฅผ ๋“ค์–ด, ์‚ฌ์ „์„ [String] array๋กœ ์š”์•ฝํ•ด๋ฒ„๋ฆด ๊ฒƒ์ด๋ผ๋ฉด, Result๋Š” [String]์ด ๋  ๊ฒƒ ์ž…๋‹ˆ๋‹ค.

์‚ฌ์ „, ํด๋กœ์ ธ -> ์ปฌ๋ ‰์…˜์„ ๊ฐ„ํŽธํ•˜๊ฒŒ ์ฃผ๋ฌด๋ฅด๊ธฐ

 

์šฉ๋„ : 1). ์–ด๋ ˆ์ด ํˆฌ ๋”•์…”๋„ˆ๋ฆฌ ํ”„๋ฆฌํ€€์‹œ ์นด์šดํ„ฐ, 2). ํ”„๋ฆฌํ€€์‹œ ํˆฌ ์–ด๋ ˆ์ด ๋Š˜์–ด๋†“๊ธฐ 3). ์‚ฌ์ „์˜ ๊ฐ’๋“ค ์š”์•ฝ๊ฐ’ ๋‚ด์–ด๋†“๊ธฐ

 

          ์—ฐ์Šต 1).  ์ปฌ๋ ‰์…˜.reduce(into : ){  }  < String(์‹œํ€€์Šค) -> ์‚ฌ์ „ >

์ต์ˆ™ํ•ด์ง€๋ ค๋ฉด, ๊ทธ๋ƒฅ ๋ฌดํ•œ ์—ฐ์Šต. ๋ฌดํ•œ์œผ๋กœ ์ œ๋Œ€๋กœ ์—ฐ์Šตํ•˜๋ฉด, ๋‡Œ์—์„œ ์ž๋™์œผ๋กœ ํŒจํ„ด์„ ๋งŒ๋“ ๋‹ค๊ณ  ํ•˜๋„ค์š”. ^^

์ด๋ฒˆ์—” ํ•œ ์ŠคํŠธ๋ง์ด๋ผ๋Š” ์‹œํ€€์Šค๋ฅผ ์‚ฌ์ „์œผ๋กœ reduceํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. into์— ์ง‘์–ด๋„ฃ์€ [ : ] ๋นˆ ์‚ฌ์ „์ด inout์œผ๋กœ ๋ ˆํผ๋Ÿฐ์Šค ๋ณ€์ˆ˜์ฒ˜๋Ÿผ counts๋กœ ๋“ค์–ด๊ฐ€๊ณ , ์ดํ„ฐ๋ ˆ์ด์…˜ํ•  ๋•Œ๋งˆ๋‹ค,  ๊ฐ ์š”์†Œ๊ฐ€ letters์— ์ง€์ •๋ฉ๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ ๋ ˆํผ๋Ÿฐ์Šค ๋ณ€์ˆ˜์ธ ์‚ฌ์ „ count์˜ ๊ฐ’์ด ๋ฆฌํ„ด๋ฉ๋‹ˆ๋‹ค. 

let letters = "abracadabra"
let letterCount = letters.reduce(into: [:]) {
    counts, letters in // ์‚ฌ์ „์ด๋ž‘์€ ๋‹ค๋ฅด๊ฒŒ counts <- [ : ] ๊ฐ€ ๋“ค์–ด๊ฐ€๊ณ , letters๋Š” ์ŠคํŠธ๋ง
    counts[letters, default: 0] += 1
}

// dictionary default ๊ฐ’์ถ”๊ฐ€
var letterCount2 : [String: Int] = [ : ]
letterCount2["A", default: 1] += 1
letterCount2

 

          ์—ฐ์Šต 2).  ์ปฌ๋ ‰์…˜.reduce(into : ){  }  < ์‚ฌ์ „ -> ์–ด๋ ˆ์ด >

let farmAnimals = ["๐ŸŽ": 5, "๐Ÿ•‍๐Ÿฆบ": 4, "๐Ÿ…": 6]
// dict into array of unicode animals by iterating

let animalArray = farmAnimals.reduce(into: []){
    
    (result, this: (key: String, value: Int)) in
    for _ in 0 ..< this.value {
        result.append(this.key)
    }
}

//-> ["๐Ÿ…", "๐Ÿ…", "๐Ÿ…", "๐Ÿ…", "๐Ÿ…", "๐Ÿ…", 
//"๐ŸŽ", "๐ŸŽ", "๐ŸŽ", "๐ŸŽ", "๐ŸŽ", "๐Ÿ•‍๐Ÿฆบ", "๐Ÿ•‍๐Ÿฆบ", "๐Ÿ•‍๐Ÿฆบ", "๐Ÿ•‍๐Ÿฆบ"]

 

 

* ์ฐธ๊ณ 

๊ธฐํƒ€ ์ปฌ๋ ‰์…˜ ๊ด€๋ จ ์œ ์šฉํ•œ ๋ฉ”์†Œ๋“œ๋“ค์ž…๋‹ˆ๋‹ค. ex). ์ฒ˜์Œ ๋ฐ ๋งˆ์ง€๋ง‰ ๋–จ๊ตฐ ํ˜•ํƒœ, ์ฒซ2๊ฐœ ๋งˆ์ง€๋ง‰ 2๊ฐœ๋ฅผ ์Šฌ๋ผ์ด์‹ฑํ•œ ๋ฆฌ์ŠคํŠธ, ์ฟผ๋ฆฌํ•˜์—ฌ true๋ฅผ ๋ฆฌํ„ดํ•˜๋Š” ๊ฒƒ๋“ค๋งŒ ์ œ๊ฑฐํ•˜๋Š” ๋ฉ”์†Œ๋“œ(mutating function)

// get the form that has dropped first and last.
// let removeFirst = prices.dropFirst()
// let removeFirstTwo = prices.dropFirst(2)
// let removeLast = prices.dropLast()
// let removeLastTwo = prices.dropLast(2)

// select first few, last few
// let firstTwo = prices.prefix(2)
// let lastTwo = prices.suffix(2)

// closure๋ฅผ ์ž…๋ ฅ์œผ๋กœ ๋ฐ›๋Š” ๋ฎคํ…Œ์ดํŒ… ํ”„๋กœ์‹œ์ ธ
prices.removeAll() { $0 > 15 }
// prices

//
// prices.removeAll()
// prices

 

----> 6). Lazy Collections 

     ์–ด๋–ค ์กฐ๊ฑด์— ํ•ด๋‹นํ•˜๋Š”, ๋ฌดํ•œํ•œ set์˜ ์ปฌ๋ ‰์…˜์„ ์–ด๋–ป๊ฒŒ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ์„๊นŒ. ( ์ด๊ฒƒ๋„ ๊ธฐ์–ตํ•˜์„ธ์š” !!  functional programming์„ ์ด์šฉํ•˜๋ฉด ์ƒ์‚ฐ์„ฑ์— ์ข‹๋‹ค )

 

์šฐ์„  ๋ฌธ์ œ๋ฅผ ๋“œ๋ฆด๊ฒŒ์š” !! : ์†Œ์ˆ˜(prime number)๋ฅผ ์ฒซ 10๊ฐœ๋งŒ ํ”„๋ฆฐํŠธํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์งœ๋ณด์„ธ์š”. ํด๋ž˜์‹œ์ปฌํ•˜๊ฒŒ, ๊ตณ์ด ํ•จ์ˆ˜ํ˜• ํ”Œ๊ทธ๋ž˜๋ฐ์œผ๋กœ ํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ํ•œ๋‹ค๋ฉด, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์งค ์ˆ˜๋„ ์žˆ์„ ๊ฑฐ์—์š”.

1). ์–ด๋–ค ์ž์—ฐ์ˆ˜๋ฅผ ๋„ฃ์œผ๋ฉด ์†Œ์ˆ˜์ธ์ง€ ์•„๋‹Œ์ง€ ๋ถˆ๋ฆฌ์–ธ์„ ๋ฆฌํ„ดํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ ๋‹ค.

2). ์†Œ์ˆ˜๋“ค์„ ๋ชจ์„ ์–ด๋ ˆ์ด๋ฅผ ๋งŒ๋“ ๋‹ค. ๊ทธ๋ฆฌ๊ณ , ์†Œ์ˆ˜์˜ ๊ฐœ์ˆ˜๋ฅผ ์ƒ ์นด์šดํŠธ ๋ณ€์ˆ˜๋ฅผ ๋งŒ๋“ ๋‹ค.

3). ์นด์šดํŠธ๊ฐ€ 10๋ณด๋‹ค ์ž‘์„ ๋™์•ˆ, ์†Œ์ˆ˜ ์–ด๋ ˆ์ด์—, ์œ„ ํ•จ์ˆ˜์—์„œ ํŠธ๋ฃจ๋ฅผ ๋ฆฌํ„ดํ•˜๋Š” ๊ฐ’์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

4). ์†Œ์ˆ˜๋“ค์„ 10๊ฐœ ๋ชจ์€ ์–ด๋ ˆ์ด์— .forEach{ print( $0 ) }๋ฅผ ์ ์šฉํ•œ๋‹ค.

// 1).
func isPrime( _ number : Int ) -> Bool {
    
    // 2,3 ์ด๋ฉด ๋ฐ”๋กœ true
    if number == 1 {return false}
    if number == 2 || number == 3 {return true}
    
    // ์•„๋‹ˆ๋ผ๋ฉด, ๊ทธ ์ˆซ์ž์— ๋ฃจํŠธ๋ฅผ ์”Œ์šด ๊ฐ’์„ ๋‚ด๋ฆผํ•œ ๊ฐ’์ด ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง„๋‹ค๋ฉด false
    for i in 2...Int( Double(number).squareRoot() ){
        if number % i == 0 {return false}
    }
    
    // ๊ทธ๊ฒŒ ์•„๋‹ˆ๋ผ๋ฉด, true
    return true
}

// 2).
var primes: [Int] = []
var i = 1
while primes.count < 10 {    
    if isPrime(i) {
        primes.append(i)
    }
    i += 1
}


// 3).
primes.forEach{
    print($0)
}

 

์ด๋ ‡๊ฒŒ ํ•  ์ˆ˜๋„ ์žˆ๊ฒ ์ง€๋งŒ, ๋งค์šฐ ๋‹จ๊ณ„๊ฐ€ ๋ณต์žกํ•˜๊ณ , ์Šค์œ„ํ”„ํŠธ์˜ ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ๊ฐ•์ ์„ ์‚ด๋ฆฌ์ง€ ๋ชปํ•˜๋„ค์š”.

์ด๋Ÿด ๋•Œ๋Š”, 

1). ๋ฌดํ•œ ๋ ˆ์ธ์ง€

๊ทธ๋ฆฌ๊ณ  ...

2). ์ปฌ๋ ‰์…˜.lazy์„ ์–ธ์„ ์ด์šฉํ•˜๋ฉด ์ข‹์„ ๊ฑฐ ๊ฐ™๋„ค์š”.

let primes2 = (1...).lazy  // hey swift !! it's lazy collection
//    A sequence containing the same elements as this sequence, but on which some operations, such as map and filter, are implemented lazily.
    .filter{isPrime($0)} // not mutating
    .prefix(10) // return an array of query
    // ์ด๋•Œ๊นŒ์ง€ ์‹œํ€€์Šค๊ฐ€ ์ƒ์„ฑ๋˜์ง€๋„ ์•Š๋Š”๋‹ค !!
    
primes2.forEach{ print($0) }
// ์ด๋•Œ ๋ถ€ํ„ฐ, ์‹œํ€€์Šค๊ฐ€ ํ•„ํ„ฐ๋ง์„ ๊ฑฐ์น˜๊ณ , ์ฒซ 10๊ฐœ๊ฐ€ ์ถ”๋ ค์ง„๋‹ค.

// ๋ถ„์„ !! 
(1...).lazy
    .filter{isPrime($0)}// ์ž์—ฐ์ˆ˜๋ฅผ ๊ฐ€์ง€๋Š” ๋ถ€๋ถ„์  ๋ ˆ์ธ์ง€ ๊ฐ์ฒด
    .prefix(10)

์ด๋ ‡๊ฒŒ ๋ช‡ ์ค„ ์•ˆ์— ๋๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ถ€๋ถ„์ ์œผ๋กœ๋งŒ ๋ ˆ์ธ์ง€๊ฐ€ ํ•œ์ •๋œ ๊ฐ์ฒด - ์ •์ˆ˜๋กœ ์ด๋ฃจ์–ด์ง.

( 1... ) 

์ž์—ฐ์ˆ˜๋กœ 1<= ์ธ ์ปฌ๋ ‰์…˜์€ => .lazyํ•œ ์ปฌ๋ ‰์…˜์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ๋  ๋•Œ๋งŒ ์ด ์ปฌ๋ ‰์…˜์— ๊ฐ€ํ•ด์ง€๋Š” .filer, .prefix ๋“ฑ์˜ ๋ฉ”์†Œ๋“œ๊ฐ€ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ง€๊ธˆ์€ ๊ทธ์ € ์–‘์ˆ˜์ชฝ์œผ๋กœ ๋ฌดํ•œํ•œ ์ž์—ฐ์ˆ˜ ์ปฌ๋ ‰์…˜์ด์ฃ .

 

์–ด๋””์„œ 

primes2.forEach{ print( $0 ) }๊ฐ€ ์“ฐ์˜€๋„ค์š”. ๊ทธ๋Ÿผ, ์ด์ œ ๋ฉ”์†Œ๋“œ๋“ค์„ ์ ์šฉํ•ด์•ผ๊ฒ ๋„ค์š”. ์ด๊ฒŒ => ํ•„ํ„ฐ๋ง์„ ๊ฑฐ์น˜ ์–ด๋ ˆ์ด => ์—ฌ๊ธฐ์— 10๊ฐœ๋งŒ ๋‚จ๊ธด ์–ด๋ ˆ์ด๊ฐ€ ๋ฆฌํ„ด๋˜์–ด primes๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌํ•œ ๊ฒƒ์— ๋Œ€ํ•ด ๊ฐ ์š”์†Œ๋ฅผ ํ”„๋ฆฐํŠธ ํ–ˆ์Šต๋‹ˆ๋‹ค.

 

 

๋‚ด์šฉ์„ ์ •๋ฆฌํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์˜์–ด๋กœ ์ •๋ฆฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค ^^

* ๋ ˆ์ด์ง€ ์ปฌ๋ ‰์…˜์€ ์—„๋ฐ€ํ•˜๊ฒŒ, ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋งŒ ํ•ด๋‹น ์š”์†Œ์— ๋ฉ”์†Œ๋“œ ์˜คํผ๋ ˆ์ด์…˜์„ ์ ์šฉํ•˜๋ฏ€๋กœ, ๋งค์šฐ ๋ฌดํ•œํ•˜๊ฑฐ๋‚˜ ๋งค์šฐ ํฐ ์ปฌ๋ ‰์…˜์„ ๋‹ค๋ฃจ๋Š” ๋ฐ ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค.

 

 

 

์ฝ์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

ํด๋กœ์ €์˜ˆ์ œ๋Š” ๋งŽ์ด ์—ฐ์Šตํ•ด๋ณด์„ธ์š” ~

์ด๋ ‡๊ฒŒ ํ—ท๊ฐˆ๋ฆฌ๊ฑฐ๋‚˜, ๋””ํ…Œ์ผ์ด ๋ณต์žกํ•œ ๊ฐœ๋…์˜ ๊ฒฝ์šฐ์—๋Š” ์ข‹์€ ์˜ˆ์ œ๋ฅผ ์ˆ˜์—†์ด ํ’€์–ด๋ณด๋ฉด์„œ

๊ณ ๋‡Œํ•˜๊ณ , ๊ฒฝํ—˜ํ•˜๋Š” ์ˆ˜ ๋ฐ–์— ์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋งŒ์•ฝ ํด๋กœ์ € ์˜ˆ์ œ๊ฐ€ ํ•„์š”ํ•˜์‹œ๋ฉด 7616tjrgml@naver.com์œผ๋กœ ๋ฉ”์ผ ์ฃผ์‹œ๋ฉด ์ข‹์€ ์˜ˆ์ œ๋“ค ๋ณด๋‚ด๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.