ทำตัวเหล่ท่อไปกับ Higher order functions in Swift

Pattaravadee Luamsomboon
Finnomena
Published in
4 min readJun 11, 2021

--

หวัดดีชาวโลก นี่เราเดินทางเข้าสู่อีกครึ่งปีของปี 2021 แล้วหรอเนี่ย เร็วมากกกกก เอาล่ะมาเข้าเรื่องกันเถอะเนอะ สำหรับ blog นี้ก็จะตามหัวข้อเลยนะ เราจะมาพูดถึง Higher order functions in Swift ซึ่งเนื้อหาจะมีอะไรยังไงบ้าง ไปดูกันโลดดดดดด

สิ่งที่จะพูดถึงในวันนี้

  • อะไรคือ Higher order functions
  • ประโยชน์ของ Higher order functions
  • Higher order functions ที่เรานิยมนำมาใช้กันมากที่สุด

มาเริ่มกันที่หัวข้อแรกกันเลยดีกว่า

อะไรคือ Higher order functions

สำหรับชาว iOS ที่เขียนภาษา Swift จะมีคำอธิบายแค่ 2 ข้อเท่านั้น สั้นๆ กระชับ และเข้าใจง่ายแน่นอน
1. function ที่รับ argument มาเป็น function หรือ closures
2. function ที่มีการ return มาเป็น function หรือ closures

เนี่ยยยยยมีแค่นี้เลย เพียง 2 ข้อสั้นๆ กระชับเข้าใจได้ง่าย 😁😁😁

มาดูตัวอย่างที่เขียนกัน

จะเห็นว่า function combineUserData จะเป็น Higher order functions เพราะมีการรับ function เข้ามาเป็น argument ซึ่ง function ที่จะถูกส่งเข้ามาจะเป็นการรับ string 2 ตัวเข้ามาและทำอะไรซักอย่าง แล้ว return ออกมาเป็น string และจากโค้ดจะได้ผลลัพธ์ตามรูปด้านล่างนี้

ประโยชน์ของ Higher order functions

  • โค้ดจะอ่านง่ายได้จาก function เลย และโค้ดจะ clean และ clear มาก
  • ง่ายต่อการ reuse กับ function อื่นๆ
  • และข้อสุดท้ายสำคัญมากๆ ใช้แล้วจะรู้สึกเหล่ท่อมากๆ 😂😂😂

Higher order functions ที่เรานิยมนำมาใช้กันมากที่สุด

  • map
  • compactMap
  • flatMap
  • reduce
  • sorted
  • filter

มาเริ่มดูกันที่ตัวแรกก่อนเล้ยยยยยย

  • map จะเป็นการเปลี่ยน element แต่ละตัวของ array เดิม ใน closure แล้วส่งค่าของ array ใหม่กลับมา

ตัวอย่างการใช้ map

let countries: [String] = ["thailand", "india", "england", "france", "usa"]

จากตัวอย่างข้อมูลด้านบน ถ้าหากเราต้องการให้ตัวหนังสือเป็นตัวใหญ่ทั้งหมด แบบไม่ใช้ Higher order functions ก็คงจะเขียน for loop ในลักษณะนี้กันเนอะ

var uppercasedWordsForLoop: [String] = [String]()
for country in countries {
uppercasedWordsForLoop.append(country.uppercased())
}

แต่ถ้าหากว่าเราจะใช้ Higher order functions ล่ะจะเป็นยังไง

let uppercasedWords = countries.map { $0.uppercased() }

ผลลัพธ์

จะเห็นได้ว่าตอนเราใช้ for loop โค้ดจะค่อนข้างยาว แถมยังต้องสร้าง array อีกตัวมา append element ทีละตัวด้วย และการใช้ map โค้ดจะสั้นกระชับ และ clear ด้วย

  • compactMap จะเป็น function ที่คล้ายกันกับ map เลย เพียงแต่ compactMap จะ returns array ที่จะไม่มีค่า null

ตัวอย่างการใช้ compactMap

let countries: [String?] = ["thailand", nil, nil, "india", "england", nil, "france", "usa"]
let map = countries.map { $0?.uppercased() }
let compactMap = countries.compactMap { $0?.uppercased() }

ผลลัพธ์

จากผลลัพธ์จะเห็นว่าถ้าหากเราใช้ map ตัว array ของเราจะยังคงมี element ที่เป็น null อยู่ด้วย แต่หากใช้ compact map เราจะได้ array ที่ไม่มีค่า null นั่นเอง

  • flatMap จะช่วยเราจัดการกับพวก nested array หากเราใช้ flatMap กับ nested array ใดๆ จะทำให้ array นั้นกลายเป็น array 1 มิติ และเรายังใช้ flatMap เหมือน compactMap ด้วย คือค่าใน array จะไม่มี null นั่นเอง

ตัวอย่างการใช้ flatMap

let countries: [[String]] = [["thailand", "india"], ["england", "france", "usa"]]
let flatMap = countries.flatMap { $0 }

ผลลัพธ์

  • reduce เป็น function ที่ให้เรา combine ทุก elements ใน array แล้ว return ข้อมูลบางอย่างออกมาด้วย type อะไรก็ได้ (Generic)

ตัวอย่างการใช้ reduce (แบบเต็ม)

let numbers: [Int] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let sum = numbers.reduce(0, { x, y in
return x + y
})

ตัวอย่างการใช้ reduce (แบบสั้น)

let sum2 = numbers.reduce(0, { $0 + $1 })

ตัวอย่างการใช้ reduce (แบบสั้นยิ่งกว่าาาาา)

let sum3 = numbers.reduce(0, +)

ผลลัพธ์

  • sorted เป็น function ที่ทำงานตามชื่อเลย ก็คือการเรียงข้อมูลใร array นั่นเอง

ตัวอย่างการใช้ sorted

let toSort = [5, 3, 8, 2, 10]let sorted = toSort.sorted()

ผลลัพธ์

จากผลลัพธ์ ถ้าหากเราเรียกใช้ sorted แบบด้านบนตัวเลขจะถูกเรียงจากน้อยไปหามาก แต่ถ้าหากเราต้องการให้เรียงจากมากไปน้อยล่ะ จะเขียนยังไง ไปดูกัน

ตัวอย่างการใช้ sorted เรียงจากมากไปน้อย

let sortedShortHand = toSort.sorted { (num1, num2) -> Bool in
return num1 > num2
}

ตัวอย่างการใช้ sorted เรียงจากมากไปน้อย (แบบสั้น)

let sortedShorterHand = toSort.sorted { $0 > $1 }

ตัวอย่างการใช้ sorted เรียงจากมากไปน้อย (แบบสั้นยิ่งกว่าาาาา)

let sortedShortestHand = toSort.sorted(by: >)

ผลลัพธ์

  • filter จะเป็นการ filter element ของ array เดิมด้วยเงื่อนไขที่กำหนด และใน closure จะส่งค่าของ array ใหม่กลับมา เช่น การหาเลขคู่/คี่ ใน array ของตัวเลข เป็นต้น

ตัวอย่างการใช้ filter

let numbers: [Int] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let filter = numbers.filter { $0 % 2 == 0 }

ผลลัพธ์

จะเห็นได้ว่าจากตัวอย่างทั้งหมด แต่ละ function จะทำให้เราเขียนโค้ดได้สั้นกระชับมากขึ้น และตัว function ก็ค่อนข้าง clear เมื่อได้อ่าน ซึ่งมันจะเป็นผลดีต่อเราและทีมของเราแน่นอน และที่สำคัญเขียนออกมาแล้วยังเหล่ท่อไปอี้กกกกก

สำหรับ blog นี้เนื้อหาก็จะมีเพียงเท่านี้ หวังว่าจะเป็น blog ที่มีประโยชน์กับทุกคนที่ได้เข้ามาอ่าน แล้วเจอกันใหม่ใน blog ฮ้าฟฟฟฟ

--

--