เนื้อหาตอนต่อไปนี้ เราจะมาดูเกี่ยวกับการใช้งาน Library หรือเครื่องมือ
ที่ช่วยให้เราสามารถจัดการ การทำงานของโปรแกรมได้ง่าย และสะดวกมากขึ้น
ในภาษา Dart จะมี library สำหรับแต่ละ platform เช่น ใช้สำกรับพัมนาเว็บ
หรือที่เรียกว่า Web platform , ใช้สำหรับพัฒนา Application ไม่ว่าจะเป็น Mobile
หรือ Desktop ที่เรียกว่า Native platform เหล่านี้เป็นต้น
แต่ในที่นี้เราจะมาแนะนำ เฉพาะในส่วนของ Library ที่ใช้บ่อย และรองรับในหลายๆ
platform หรือก็คือ เป็น library พื้นฐานที่มีการนำไปใช้งานได้กับ platfrom อื่นๆ โดยใน
บทความนี้จะพูดถึงในส่วนของ Library dart:core
สามารถทดสอบการเขียนโปรแกรมผ่านเว็บไซต์ DartPad
การใช้งาน Library
ในการใช้งาน library ต่างๆ ที่ภาษา Dart เตรียมไว้ให้ เราจะใช้คำสั่ง import ตามด้วย ชื่อ library ที่จะใช้งาน ดังนี้
import 'dart:async'; import 'dart:math'; import 'dart:collection'; import 'dart:convert'; import 'dart:developer'; import 'dart:typed_data'; void main() { }
สามารถเลือก import เฉพาะ library ที่ต้องการใช้งาน ข้างต้น เราทำการ import library ที่รองรับในหลายๆ platform เป็นตัวอย่าง
โดยปกติและเป็นวิธีที่เหมาะสมคือ เราควรทำการ import library ที่ภาษา Dart เตรียมไว้ให้ ไว้ด้านบนสุดของโค้ด ดูแนวทางดังนี้
// Dart library import 'dart:async'; import 'dart:math'; // library package จากที่อื่นๆ import 'package:bar/bar.dart'; import 'package:foo/foo.dart'; // library package ที่เรากำหนดขึ้น import 'package:my_package/util.dart'; // ส่วนอื่นๆ ที่ใช้งานเพิ่มเติม เช่น ชุดไฟล์คำสั่ง ที่เราสร้างขึ้น หรือ class เพิ่มเติม import 'util.dart'; void main() { }
การใช้งาน dart:core
สำหรับ dart:core library จะเป็นตัวจัดการเกี่ยวกับ ชนิดข้อมูล build-in ต่างๆ ไม่วาจะเป็นตัวเลข ข้อความ อาเรย์ รวมถึงฟังก์ชั่นต่างๆ
ที่มีในทุกๆ โปรแกรมภาษา dart โดย library นี้จะถูก import มาให้โดยอัตโนมัติ เราจะมีดูฟังก์ชั่นต่างๆ ที่จำเป็นและใช้บ่อย ซึ่งเป้นเพียง
บางส่วนเท่านั้น
การแสดงข้อความทาง console
คำสั่ง print() เป็นคำสั่งที่ใช้ในการแสดงค่าข้อความของ สิ่งที่ต้องการหรือของ object ที่ต้องการ เราพบเห็นบ่อยมากในการทดสอบ
การเขียนโปรแกรม อย่างที่เราทราบว่า ทุกๆ อย่างในภาษา Dart เป็น object และมี toString() method เป็นตัวที่แสดงข้อความของ
object นั้นๆ โดยอัตโนมัติ ดูตัวอย่าง
void main() { var obj; print(obj); // null print(obj.toString()); // null print(obj.runtimeType); // Null String mystr = "Hello"; print(mystr); // Hello print(mystr.toString()); // Hello print(mystr.runtimeType); // String }
สังเกตว่า จะกำหนด toString() หรือไม่ ก็จะได้ค่า ข้อความของ object นั้น เหมือนกัน
ส่วน runtimeType เป็น property การระบุว่า เป็น object ชนิดใด อย่าง obj จะเป็น Null Object และ mystr เป็น String Object
การจัดการตัวเลข Number
ใน dart:core จะกำหนด num, int และ double class ที่มีคำสั่งเครื่องมือ และการจัดการเกี่ยวกับตัวเลข เราสามารถทำการแปลงข้อความ
จาก string ให้เป็นตัวเลข interger (จำนวนเต็ม) หรือ double (เลขทศนิยม) โดยใช้คำสั่ง parse() ดูตัวอย่าง ด้านล่าง
void main() { String a = "37"; print(a.runtimeType); // String print(int.parse(a)); // ค่าที่ถูกแปลงเป็น int แล้ว เท่ากับ 37 print(int.parse(a).runtimeType); // ชนิดข้อมูลเปลี่ยน int String hexValue = "0x42"; // ข้อความเลขฐาน 16 int decVelue = int.parse(hexValue); // แปลงเป็น int print(decVelue); // 66 print(decVelue.runtimeType);// int // การแปลงค่า จากข้อความเป็นตัวเลข ต้องมีรูปแบบที่ถูกต้องกับชนิดข้อมูลนั้นๆ String decimalValue = "42.1"; // บรรทัดด้านล่างนี้ error // Uncaught Error: FormatException: 42.0 รูปแบบข้อมูลไม่ถูกต้อง int decValue2 = int.parse(decimalValue); // ไม่สามารถแปลง เป็นเลขจำนวนเต็มได้ // ควรใช้เป้น double decValue2 = double.parse(decimalValue); // หรือ กรณีเราต้องการให้รองรับทั้ง เลขจำนวนเต็ม และทศนิยม คารใช้เป็น num // ดังนี้ num decValue2 = num.parse(decimalValue); }
สำหรับตัวอย่างที่ error ในโค้ดด้านบน จะเห็นว่า ข้อความ "42.0" เป็นข้อความในรูปแบบตัวเลขทศนิมยม ซึ่งหากเราใช้คำสั่ง parse()
โดยต้องการแปลงเป็นเลขจำนวนเต็ม int จะเกิด error ขึ้น ทั้งนี้เพราะ เลขจำนวนเต็ม จะไม่มีทศนิยม ดังนั้น วิธีป้องกัน หรือแนวทางสำหรับ
การใช้งานเกี่ยวกับตัวเลขทศนิยม เราสามารถใช้เป้น double หรือ หากต้องการให้รองรับทั้ง int และ double ก็ให้ใช้เป็น num แทน
ซึ่ง num ชนิดของข้อมูลจะขึนอยู่กับค่าของค่ามูลนั้น เช่น หากเป็น "42.0" ค่าที่แปลงจะเป็น 42 ได้ num เป็นชนิดข้อมูล int และถ้าหาก
เป้น "42.1" จะได้ num เป็น 42.1 เป็นชนิดข้อมูล double และไม่เกิด error ขึ้น
ลักษณะของข้อมูลเปลี่ยนแปลงไปตามค่าของข้อมูล เราจะเรียกว่า runtime type หรือชนิดข้อมูลในขณะที่ทำงานอยู่ในขณะนั้น
ในการใช้งาน parse() เราสามารถระบุ ประเภทเลขฐานของข้อมูลตัวเลขนั้น ด้วยโดยใช้ radix parameter ดังนี้
String hexValue = "42"; // ข้อความ เลข 42 ที่เป็นเลขฐาน 16 int decVelue = int.parse(hexValue, radix: 16); // แปลงเป็น int
ในการจัดการตัวเลข เราสามารถแปลงตัวเลข int หรือ double กลับมาเป็นชนิดข้อมูล String ได้โดยใช้คำสั่ง toString() หรือถ้าต้องการ
ให้ตัวเลขนั้นๆ แสดงค่่าทศนิยม ตามจำนวนที่ต้องการ ก็สามารถใช้งานคำสั่ง toStringAsFixed() หรือหากต้องการค่าเลขทศนิยมที่มีความ
แม่นยำถูกต้องเข้าไปอีก ก็สามารถใช้คำสั่ง toStringAsPrecision() ก็ได้เช่นกัน
void main() { num a = 123.456; // ต้องการแปลงเป้นข้อความเลขทศนิยม 2 ตำแหน่ง var b = a.toStringAsFixed(2); print(b.runtimeType); // String print(b);// 123.46 // ต้องการค่าความแม่นยำที่ 2 ตำแหน่งแรก var c = a.toStringAsPrecision(2); print(c.runtimeType); // String print(c);// 1.2e+2 // e+x เท่ากับ 10 ยกกำลัง x เช่น e+2 เท่ากับ 10 * 10 // 1.2 * 100 = 120 // เมื่อลองแปลงค่า c กลับมา เป็นตัวเลข print(num.parse(c)); // 120 // ค่าตำแหน่งที่ 3 จาก 123.456 คือ 3 เมื่อใช้หลักการปัดเศษ จะได้เป็น 0 // ถ้าหากค่าเป็น 125.456 ตัวที่ 3 คือ 5 จะได้เป็น 130 แทน เพราะ 5 ปัดขึ้น }
ดูคำสั่ง และการจัดการเพิ่มเติม ได้ที่
การจัดการข้อความ String และ Regular Expression
ในภาษา Dart จะใช้รูปแบบ string เป็น UTF-16 หรือก็คือมีการจัดรูปแบบข้อมูลแบบ 16 บิตเรียงต่อเนื่องกันและแก้ไขไม่ได้ นอกจาก
การใช้งานคำสั่งต่างๆ ใน string class เพื่อจัดการกับข้อความ แล้ว เรายังสามารถใช้งาน Regular Expression (RegExp object) ในการ
ค้นหาหรือแทนค่าข้อความ string ได้
ตัวอย่างคำสั่ง จาก string class ที่เราน่าจะคุ้นเคยในการใช้งานภาษาโปรแกรมอื่นๆ เช่น
แยกข้อความด้วย split() หาคำหรือข้อความบางส่วนด้วย contains() หาค่าหรือคำที่ขึ้นต้นด้วย startsWith() หาค่าหรือคำที่ลงท้าย
ด้วย endsWith() เหล่านี้เป็นต้น ยังมีคำสั่งอีกมากใน string class
การค้นหาคำหรือข้อความใน String
เราสามารถหาตำแหน่งของค่าใดๆ หรือคำในข้อความ string หรือเราสามารถจะหาคำหรือข้อความเริ่มต้น คำหรือข้อความลงท้ายได้
void main() { String title = "การใช้งาน Library ที่จำเป็นและใช้บ่อย ในภาษา Dart เบื้องต้น"; // หาว่ามีค่า หรือคำที่ต้องการใน ข้อความหรือไม่ case sensitive print(title.contains('dart')); // false print(title.contains('Dart')); // true print(title.contains('ภาษา')); // true // ขึ้นต้นด้วยค่าที่ต้องการหรือไม่ case sensitive print(title.startsWith('การ')); // true // ลงท้ายด้วยค่าที่ต้องการหรือไม่ case sensitive print(title.endsWith('ต้น')); // true // หาตำแหน่งของคำที่ต้องการ ถ้ามี case sensitive ถ้าไม่มีได้ค่าเป็น -1 print(title.indexOf('dart')); // -1 print(title.indexOf('Dart')); // 45 }
การตัดคำ แยกค่าหรือคำจากข้อความ String
เราสามารถที่จะแยกตัวอักขระ แต่ละตัวจากข้อความ ออกมาอยู่ในรูปแบบ String หรือ int ตามลำดับ
void main() { String title = "ภาษา Dart เบื้องต้น"; // การตัดคำบางส่วนจากข้อความ print(title.substring(0, 4)); // "ภาษา" print(title.substring(4)); // " Dart เบื้องต้น" // สร้างลิสรายการ ด้วยการแยกคำด้วยรูปแบบที่ต้องการ เช่น ช่องว่าง var partStr = title.split(" "); print(partStr.length); // 3 print(partStr[0]); // ภาษา print(partStr[2]); // เบื้องต้น print(partStr.runtimeType); // List<String> // การใช้ index ระบุตำแหน่งตัวอักขระ ที่ต้องการแยกมาจากข้อความ print(title[0]); // ภ print(title[0].runtimeType); // ค่าที่แยกมาเป็น String // การแยกตัวอักขระ ออกจากข้อความ แล้วสร้าง เป็น ลิสรายการ // โดยใช้คำสั่ง split("") var chars = title.split(""); print(chars.runtimeType); // List<String> // เราสามารถใช้คำสั่ง for วนลูปแสดงแต่ละตัวอักขระได้ดังนี้ for(var char in chars){ // วนลูแสดงตัวอักขระในลิสรายการ print(char); // แสดงอักขระ ตัวอักษร } // แสดงลิสรายการ ในรูปแบบรหัส UTF-16 ของตัวอักขระแต่ละตัวในข้อความ print('ภ'.codeUnits); // [3616] print(title.codeUnits); // ouput: // [3616, 3634, 3625, 3634, 32, 68, 97, 114, // 116, 32, 3648, 3610, 3639, 3657, 3629, 3591, // 3605, 3657, 3609] // จะเห็นว่าตัว "ภ" จะมีรหัส UTF-16 เป็น 3616 // ซึ่ง "ภ" เป็นตัวอักขระตัวแรก ของลิสรายการ หรือ array var codeUnit = title.codeUnits; print(codeUnit.runtimeType); // CodeUnits // สร้างข้อมูลชนิด List จากค่าของข้อมูล CodeUnits โดยใช้คำสั่ง toList() var codeUnitList = codeUnit.toList(); print(codeUnitList.runtimeType); // List<int> // เราสามารถอ้างอิงค่าตามตำแหน่งของ index ของ List print(codeUnitList[0]); // 3616 }
การแปลงข้อความ เป็นตัวพิมพ์ใหญ่ หรือตัวพิมพ์เล็ก
รูปแบบคำสั่งนี้ จะใช้งานได้ในบางภาษา ส่วนใหญ่จะใช้กับภาษาอังกฤษ
void main() { String title = "ภาษา Dart Programming เบื้องต้น"; print(title.toLowerCase()); // ภาษา dart programming เบื้องต้น print(title.toUpperCase());// ภาษา DART PROGRAMMING เบื้องต้น }
การตัดช่องว่าง และการตรวจสอบค่าว่างใน String
เราสามารถตัดช่องว่าง ที่อยู่ด้านหน้าหรือด้านหลังของข้อความ string ถ้ามีออก โดยใช้คำสั่ง trim() หรือใช้คำสั่ง trimLeft() หรือ
trimRight() กรณีต้องการตัดเฉพาะส่วนที่ต้องการอย่างใดอย่างหนึ่ง
สำหรับการตรวจสอบว่ามีข้อความนั้นเป็นค่าว่างหรือไม่ สามารถใช้คำสั่ง isEmpty() หรือ isNotEmpty()
* ค่าว่าง กับ ช่องว่างหรือ space จะคนละความหมายกัน ค่าว่างคือมีความยาวของ string เท่ากับ 0 (length เท่ากับ 0)
void main() { String title = " ภาษา Dart เบื้องต้น "; print(title.trim()); // "ภาษา Dart เบื้องต้น" print(title.trimLeft());// "ภาษา Dart เบื้องต้น " print(title.trimRight());// " ภาษา Dart เบื้องต้น" // string ช่องว่าง var spaceString = " "; print(spaceString.length); // 1 print(spaceString.isEmpty); // false print(spaceString.isNotEmpty); // true // string ค่าว่าง var emptyString = ""; print(emptyString.length); // 0 print(emptyString.isEmpty); // true print(emptyString.isNotEmpty); // false }
การแทนที่ค่าบางส่วนของ String
อย่างที่ได้อธิบายไปในตอนต้นว่า ตัวแปร String object จะเป้นค่าที่ไม่สามารถแก้ไขได้ นั่นหมายความว่า เราสามารถสร้าง string ใหม่ๆ
ขึ้นมาได้ แต่ไม่สามารถแก้ไขตัวเดิมได้ ดังนั้นการแทนที่ค่าบางส่วนของ string จึงหมายถึงการสร้างข้อความ string ขึ้นมาใหม่โดยไม่มีการ
เปลี่ยนแปลงค่าของข้อความต้นฉบับ
void main() { var greetingTemplate = 'สวัสดี, NAME!'; // ตรวจสอบข้อความที่ตรงกับรูปแบบ ด้วย Regular Expression // จากนั้นใช้คำสั่้ง replaceAll() แทนที่คำที่ตรงทั้งหมดที่ตรงกับรูปแบบ // ด้วยข้อความว่า "Ebiwayo" var greeting = greetingTemplate.replaceAll(RegExp('NAME'), 'Ebiwayo'); // จะเป็นการสร้าง string ข้อความใหม่ขึ้นมา print(greeting); // สวัสดี, Ebiwayo! // การใช้ replaceAllMapped() แทนที่ กลุ่มของข้อมูลที่ตรงกับรูปแบบ // แล้วประมวลผลการแทนที่ค่าตามต้องการ var originalStr = "I have a secret now!"; var newString = originalStr.replaceAllMapped( RegExp(r'\b(\w*?)([aeiou]\w*)', caseSensitive: false), (Match m) => "${m[2]}${m[1]}${m[1].isEmpty ? 'way' : 'ay'}"); print(newString);// Iway avehay away ecretsay ownay! // การใช้ replaceFirst() แทนตัวแรกที่ตรงกับรูปแบบ var doubleStr = "0.0001"; print(doubleStr.replaceFirst(RegExp(r'0'), '')); // '.0001' // ใช้ parameter ตัวที่ 3 เพื่อระบุตำแหน่ง index ค่าเริ่มต้นตัวแรกเป็น 0 // ดังนั้น 0 ที่ index = 1 คือตัวที่ 2 จึงถูกแทนที่ด้วยเลข 7 print(doubleStr.replaceFirst(RegExp(r'0'), '7', 1)); // '0.7001' // การใช้ replaceRange() แทนทีจากการระบุตำแหน่ง เริ่มต้น และสิ้นสุด var myStr = "ภาษา Dart"; print(myStr.replaceRange(0,2,'')); // แทน 2 ตัวแรกด้วยค่าว่าง จะได้เป็น "ษา Dart" print(myStr.replaceRange(4,null,' Kotlin')); // แทนที่ตำแหน่ง 4 เป็นตันไป จะได้เป็น "ภาษา Kotlin" }
การสร้างข้อความ String
เราได้เคยอธิบายเกี่ยวกับตัวแปร String ไปบ้างแล้วในบทความ http://niik.in/939
ซึ่งนอกจากรูปแบบการใช้งานการกำหนดตัวแปร string ตามที่อธิบายไปแล้ว เรายังสามารถใช้งาน StringBuffer class ในการสร้าง
ข้อความ string ใหม่ได้อีกด้วย โดยการใช้งาน StringBuffer จะไม่มีการสร้างข้อความใหม่ขึ้นมา จนกว่าจะมีการเรียกใช้งานคำสั่ง
toString() ดูตัวอย่างคำสั่งต่างๆ ที่ใช้งานร่วมกับ StringBuffer ด้านล่าง
void main() { // สร้างข้อความด้วย StringBuffer class var sb = StringBuffer(); // จากนั้นกำหนด การทำงานแบบต่อเนื่องในรูปแบบ cascade // อ่านที่ http://niik.in/940 // เป็นการกำหนดการทำงานให้กับ object หนึ่งอย่างต่อเนื่อง // คำสั่ง writeAll() สามารถสร้างข้อความจาก List และกำหนดตัวคั่นได้ sb ..write('Use a StringBuffer for ') ..writeAll(['efficient', 'string', 'creation'], ' ') ..write('.'); print(sb.runtimeType); // StringBuffer ยังไม่ใช่ String object // StringBuffer จะยังไม่สร้างข้อความขึ้นมา หรือก็คือยังไม่ได้เป็น String // จนกว่าจะเรียกใช้คำสั่ง toString(); var fullString = sb.toString(); print(fullString.runtimeType); // String // ทดสอบแสดงค่าของทั้งสอง จะได้ข้อความเหมือนกัน // แต่ไม่ใช่ชนิด ข้อมูลเดียวกัน print(sb); // "Use a StringBuffer for efficient string creation." print(fullString); // "Use a StringBuffer for efficient string creation." print(sb == fullString); // false }
การใช้งาน Regular expressions
ในภาษา Dart จะมีรูปแบบการใช้งาน regular expression เหมือนกับ JavaScript โดยใช้ RexExp class ในการจัดการ ซึ่งการใช้งาน
regular expression จะทำให้การกำหนดรูปแบบการค้นหาข้อความเป็นไปอย่างมีประสิทธิภาพ และจัดการได้มากขึ้น
มีเนือหาเกี่ยวกับ regular expression ในเวอร์ชั่น php ซึ่งใช้งานในรูปแบบคล้ายกัน ดูได้ที่ http://niik.in/396
void main() { // กำหนดรูปแบบ pattern ของตัวเลขตั้งแต่ 1 ตัวขึ้นไป // การใช้ตัว r ด้านหน้า เป็นการกำหนด raw string ให้กับ \d // เป็นการบอกโปรแกรมว่า ไม่ต้องแปลงค่า \d เป็นค่าอื่น เช่นเดียวกับ // \n ที่หากไม่ใช่ raw string ก็จะเป็นการขึ้นบรรทัดใหม่ // ดูเพิ่มเติม http://niik.in/939 // จะได้ \d คือตัวเลขทุกตัว และ + คือมีอย่างน้อย 1 ตัวขึ้นไป var numbers = RegExp(r'\d+'); // กำหนดตัวแปรสำหรับทดสอบ แบบข้อควมมทั้งหมด และแบบมีตัวเลขปน var allCharacters = 'llamas live fifteen to twenty years'; var someDigits = 'llamas live 15 to 20 years'; // ใช้คำสั่ง contains() หาว่ามีตัวเลขหรือไม่ โดยใช้ pattern print(allCharacters.contains(numbers)); // false ไม่มี print(someDigits.contains(numbers)); // true มีตัวเลข // แทนค่าทุกค่า ที่ตรงตามรูปแบบ pattern ที่กำหนด ด้วย "XX" var exedOut = someDigits.replaceAll(numbers, 'XX'); print(exedOut); // llamas live XX to XX years // จะเห็นว่าตัวเลขถูกแทนที่ด้วย "XX" }
นอกจากเราจะใช้งาน RexExp class ร่วมกับ method หรือคำสั่งของ String แล้ว เรายังสามารถใช้งานร่วมกับ method ของ RexExp
โดยตรงได้ ดังนี้
void main() { // กำหนดรูปแบบ pattern ของตัวเลขตั้งแต่ 1 ตัวขึ้นไป var numbers = RegExp(r'\d+'); // กำหนดตัวแปรสำหรับทดสอบ แบบข้อควมมทั้งหมด และแบบมีตัวเลขปน var allCharacters = 'llamas live fifteen to twenty years'; var someDigits = 'llamas live 15 to 20 years'; // ใช้คำสั่ง hasMatch() เช็คว่า ข้อความนั้นๆ มีตรงกับ pattern หรือไม่ print(numbers.hasMatch(someDigits)); // true print(numbers.hasMatch(allCharacters)); // false // ทดสอบใช้ค่าตรงข้าม print(!numbers.hasMatch(allCharacters)); // true // ใช้คำสั่ง allMatches() วนลูปจัดการค่าที่ตรงตามรูปแบบ var matchList = numbers.allMatches(someDigits); for (var match in matchList) { print(match.group(0)); // แสดง 15 และ 20 ตามลำดับ } }
สามารถดูคำสั่ง เพิ่มเติมของแต่ละส่วน ในเนื้อหาข้างต้นได้ที่
การจัดการกลุ่มข้อมูล Collections
สำหรับเนื้อหาเกี่ยวกับการใช้งานชุดข้อมูล หรือกลุ่มข้อมูลที่มีการจัดเก็บแบบรวมกันเป็นชุดๆ ในรูปแบบที่แตกต่างกัน ซึ่งจะมีชนิดข้อมูล
ที่เป็น List, Set และ Map โดยเนื้อหาส่วนนี้ ขอให้เราไปทบทวนได้ที่บทความเกี่ยวกับชนิดข้อมูลในภาษา Dart
ประเภทข้อมูล และใช้งานตัวแปร Variable ในภาษา Dart เบื้องต้น http://niik.in/939
https://www.ninenik.com/content.php?arti_id=939 via @ninenik
และจะขอธิบายการใช้งานบางคำสั่ง ที่มักพบเห็นและมีการใช้บ่อย ดังนี้
การใช้งาน List
void main() { // สร้าง List object var vegetables = List(); // ใช้ isEmpty เช็คว่างหรือไม่ ใช้ค่า isNotEmpty เช็คตรงข้าม print(vegetables.isEmpty); // true // หรือสร้าง List โดยการกำหนดค่า โดยตรง คล้ายกำหนด array var fruits = ['apples', 'oranges']; // เพิ่มรายการใน List โดยใช้คำสั่ง add() fruits.add('kiwis'); // เพิ่มหลายค่าทีเดียวพร้อมกันโดยใช้คำสั่ง addAll() fruits.addAll(['grapes', 'bananas']); // หาจำนวนรายการทั้งหมดใน List print(fruits.length); // 5 // ลบบางรายการออกจาก List โดยใช้คำสั่ง removeAt() ร่วมกัน indexOf() var appleIndex = fruits.indexOf('apples'); fruits.removeAt(appleIndex); print(fruits.length); // เหลือ 4 รายการ // ลบทั้งหมด fruits.clear(); print(fruits.isEmpty);// true }
การใช้งาน Set
void main() { // การสร้าง Set object var ingredients = Set(); // การเพิ่มรายการหลายอันพร้อมกัน โดยใช้คำสั่ง addAll() ingredients.addAll(['gold', 'titanium', 'xenon']); print(ingredients); // {gold, titanium, xenon} print(ingredients.length); // 3 // การเพิ่มทีละรายการ หากเพิ่มค่าที่มีอยู่แล้ว จะไม่มีผลใดๆ // เพราะ Set ค่าจะไม่ซ้ำกัน ingredients.add('gold'); print(ingredients.length); // 3 // ลบรายการออกจาก Set โดยใช้คำสั่ง remove() ingredients.remove('gold'); print(ingredients.length); // 2 // ตรวจสอบว่ามีค่านี้หรือไม่ ทดสอบครั้งละรายการโดยใช้คำสั่ง contains() print(ingredients.contains('titanium')); // true // ตรวจสอบว่ามีค่านี้หรือไม่ ทดสอบหลายรายการโดยใช้คำสั่ง containsAll() print(ingredients.containsAll(['titanium', 'xenon'])); // true // ทดสอบ การเช็คค่าของ Set 2 ตัว ว่ามีค่าใดที่ เหมือนกัน // โดยใช้คำสั่ง intersection() // สร้าง Set อีกตัว มา มี สมาชิก 2 ค่า var nobleGases = Set.from(['xenon', 'argon']); // หาค่าที่ซ้ำกัน หรือของ nobleGases และ ingredients var intersection = ingredients.intersection(nobleGases); print(intersection); // {xenon} คือ Set ของค่าที่ซ้ำกัน print(intersection.length); // 1 }
การใช้งาน Map
void main() { // สร้าง Map object โดยใช้ Map constructor. var searchTerms = Map(); // สร้าง Map object พร้อมกำหนด parameter type var nobleGases = Map<int, String>(); // การสร้าง Map object โดยกำหนดค่าใน {} ปกติใช้ string เป้น key var hawaiianBeaches = { 'Oahu': ['Waikiki', 'Kailua', 'Waimanalo'], 'Big Island': ['Wailea Bay', 'Pololu Beach'], 'Kauai': ['Hanalei', 'Poipu'] }; // การดึงค่า value ของ key ที่ต้องการ print(hawaiianBeaches['Kauai']); // ตรวจสอบว่ามี key นี้หรือไม่ print(hawaiianBeaches.containsKey('Kauai')); // true // ลบข้อมูล โดยระบุ key ที่ต้องการลบ // และตรวจสอบว่ามี key นี้หรือไม่ หลังทำการลบแล้ว hawaiianBeaches.remove('Kauai'); print(hawaiianBeaches.containsKey('Kauai')); // false ไม่มีแล้ว }
การจัดการ URIs
การใช้งานและจัดการ URIs หรือที่เรารู้จักในรูปแบบของ URL เราสามารถใช้งาน Uri class ในการทำการเข้ารหัสและถอดรหัส url
ที่ต้องการได้ โดยรูปแบบการเข้ารหัสหรือถอดรหัส ก็จะเป็นการจัดการกับตัวอักขระพิเศษต่างๆ ที่อยู่ใน url เช่น &, ?, = เหล่านี้เป็นต้น
นอกจากนั้น Uri class ยังสามารถใช้ในการแปลงขุดข้อมูลให้อยู่ในรูปแบบ url ที่ถูกต้อง หรือสามารถแยกส่วนต่างๆ ของ url เช่น
เป็น host (example.com), port (8080), scheme (http) ได้อีกด้วย
การเข้ารหัสและถอดรหัส URIs ในรูปแบบ url ที่ถูกต้อง
เราสามารถใช้คำสั่ง encodeFull() และ decodeFull() ในการเข้ารหัสหรือถอดหัส url ให้อยู่ในรูปแบบที่ถูกต้อง คำว่ารูปแบบที่ถูกต้องก็คือ
เป็นรูปแบบ url ที่เราสามารถนำไปกำหนดเป็นลิ้งค์ และใช้งานได้ทันที หรือก็คือการเข้ารหัสตัวอักขระ ที่ยกเว้นตัวที่ใช้งานปกติใน url เช่น
/ : & # ซึ่งตัวอักขระเหล่านี้ เป็นตัวอักขระพิเศษใน url หรืออาจจะเรียกว่าตัวอ้กขระ URI ก็ได้ ดูตัวอย่างด้านล่างประกอบ
void main() { // กำหนด url สำหรับทดสอบ var uri = 'https://example.com/api?greeting=Hello World'; // ใช้งานเข้ารหัส url ด้วยคำสั่ง encodeFull() ให้มีรูปแบบที่ถูกต้อง var encoded = Uri.encodeFull(uri); print(encoded); // https://example.com/api?greeting=Hello%20World // จะเห็นว่ามีเฉพาะช่องว่างเท่านั้น ที่ถูกเข้ารหัส ส่วนตัวอักขระ URI จะถูกยกเว้น // ใช้งานถอดรหัส url ด้วยคำสั่ง decodeFull() ให้กับ url ที่เข้ารหัสข้างต้น var decoded = Uri.decodeFull(encoded); print(decoded); // เหมือนการ แปลงค่ากลับ // https://example.com/api?greeting=Hello World }
การเข้ารหัสและถอดรหัสองค์ประกอบของ URIs
ในกรณีนี้จะไม่เหมือนกับรูปแบบแรก เพราะจะเป็นการเข้ารหัสและถอดรหัสตัวอักขระพิเศษทั้งหมดที่อยู่ใน url ซึ่งโดยทั่วไปแล้ว จะใช้
ในการนำค่าที่ได้ไปใช้งานต่ออีกที รูปแบบที่สองนี้ จะใช้งานคำสั่ง encodeComponent() และ decodeComponent() ตามลำดับ
ดูตัวอย่างโค้ดด้านล่างประกอบ
void main() { // กำหนด url สำหรับทดสอบ var uri = 'https://example.com/api?greeting=Hello World'; // ใช้งานเข้ารหัส url ด้วยคำสั่ง encodeComponent() var encoded = Uri.encodeComponent(uri); print(encoded); // https%3A%2F%2Fexample.com%2Fapi%3Fgreeting%3DHello%20World // จะเห็นว่ากรณีนี้ ตัวอักขระพิเศษทุกตัวใน url ถูกเข้ารหัสหมด // ใช้งานถอดรหัส url ด้วยคำสั่ง decodeComponent() ให้กับ url ที่เข้ารหัสข้างต้น var decoded = Uri.decodeComponent(encoded); print(decoded); // เหมือนการ แปลงค่ากลับ // https://example.com/api?greeting=Hello World }
สร้าง URI object จากข้อความ String
เราสามารถที่จะแปลงข้อความ string ที่มีรูปแบบเป็น url เป็น URI object ที่สามารถดึงข้อมูลแต่ละส่วนของ url นั้นๆ มาใช้งานได้
เช่น ดึงข้อมูล host หรือ port เป็นต้น โดยใช้งานคำสั่ง parse() ที่เป็น static method ดูตัวอย่างด้านล่างประกอบ
void main() { // กำหนด url สำหรับทดสอบ var url = 'https://example.com:8080/api?greeting=Hello World#place'; print(url.runtimeType); // String // แปลงเป็น URI object var uriObj = Uri.parse(url); print(uriObj.runtimeType); // _Uri // เมื่อสร้างเป็น URI object แล้ว เราก็จะมารถดึงข้อมูล property ต่างๆ ได้เช่น print(uriObj.origin); // https://example.com:8080 print(uriObj.scheme); // https print(uriObj.host); // example.com print(uriObj.path); // /api print(uriObj.port); // 8080 print(uriObj.fragment); // place print(uriObj.query); // greeting=Hello%20World // ค่า origin คือค่าในรูปแบบ scheme://host:port }
หรือเราจะสร้าง URL object โดยใช้ Uri() constructor โดยกำหนดแต่ละค่า ใน parameter ก็ได้ เช่น
void main() { // กำหนด url รูปแบบที่ถูกต้อง สำหรับทดสอบ var url = 'https://example.com:8080/api?greeting=Hello%20World#place'; print(url.runtimeType); // String // สร้าง URI object ด้วย Uri() contructor // กำหนด parameter ค่าที่ต้องการ var uriObj = Uri( scheme: 'https', host: 'example.com', port: 8080, path: '/api', query: 'greeting=Hello%20World', fragment: 'place'); print(uriObj.runtimeType); // _Uri print(uriObj); // https://example.com:8080/api?greeting=Hello%20World#place // url เป็น String ส่วน uriObj เป็น _Uri object สังเกตว่าทั้งสองค่าเหมือนกัน แต่ // ไม่เท่ากัน เราสามารถแปลง _Uri object เป็น String ด้วยใช้คำสั่ง toString() print(url == uriObj); // false // กรณีเทียบค่าเมื่อแปลงเป็น String แล้ว print(url == uriObj.toString()); // true }
สามารถดูคำสั่ง และข้อมูลเพิ่มเติม ได้ที่ Uri class
การจัดการวันที่และเวลา Date / Time
เราสามารถสร้าง DateTime object เพื่อใช้งานหรือจัดเรื่องวันที่และเวลา ด้วยการกำหนด constuctor หรือใช้การแปลงจากข้อความ
ในการใช้งานการบวกลบ วันที่ จะใช้ค่าของ Duration object มาใช้งาน ดูตัวอย่าง คำอธิบายเพิ่มเติมในโค้ดด้านล่าง
void main() { // สร้าง DateTime object ของวันที่และเวลาขณะปัจจุบัน // อิง local time zone var now = DateTime.now(); print(now); // 2019-11-29 23:25:20.208 print(now.runtimeType); // DateTime // สร้าง DateTime โดยกำหนด parameter ค่าเดียว เช่น ปีปัจจุบัน // อิง local time zone และ UTC time var thisYear1 = DateTime(2000); var thisYear2 = DateTime.utc(2000); print(thisYear1); // 2000-01-01 00:00:00.000 print(thisYear2); // 2000-01-01 00:00:00.000Z // รูปแบบ constuctor ปกติ จะเห็นว่า ปีต้องกำหนด ส่วนค่าอื่นๆ เป็น // option และ เดือนและวันมีค่าเริ่มต้นเป็น มกราคม และวันที่ 1 ตามลำดับ // DateTime.utc() ก็ใช้รูปแบบเดียวกัน /* DateTime(int year, [ int month = 1 int day = 1 int hour = 0 int minute = 0 int second = 0 int millisecond = 0 int microsecond = 0 ]) */ // เราลองสร้าง วันที่เวลา ณ ขณะนี้ดู var nowLocal = DateTime(2019, 11, 29, 23, 30, 30); var nowUtc = DateTime.utc(2019, 11, 29, 23, 30, 30); print(nowLocal); // 2019-11-29 23:30:30.000 print(nowUtc); // 2019-11-29 23:30:30.000Z // ลองแสดง property บางส่วนของ DateTime object print(nowLocal.timeZoneOffset); // 7:00:00.000000 (บวก 7 ชม.) print(nowUtc.timeZoneOffset); // 0:00:00.000000 print(nowLocal.timeZoneName); // Indochina Time print(nowUtc.timeZoneName); // UTC print(nowLocal.weekday); // 5 คือวันศุกร์ print(nowUtc.weekday); // 5 คือวันศุกร์ // ดูค่าอื่นๆ เช่น day,year,month,hour,minute,second,millisecond // ลองดูคำสั่งเกี่ยวกับวันที่บางส่วน // เปรียบเทียบก่อน หลัง และเวลาเดียวกัน print(nowLocal.compareTo(nowUtc)); // -1 // -1 เวลาเมืองไทยมาก่อน หรือเร็วกว่า 7 ชม. // 0 เวลาเมืองไทยเท่ากับ เวลาที่ UTC // 1 เวลาที่เมืองไทยหลังเวลาที่ UTC // ถ้าเราสลับตำแหน่งการเปรียบเทียบ จะได้ผลลัพธ์เท่ากับ 1 print(nowUtc.compareTo(nowLocal)); // -1 // 1 เวลาที่ UTC มากลังเวลาที่ไทย // เปรียบเทียบความต่างของเวลา คืนค่าเป็น Duration object // ในรูปแบบ Duration วัน ชั่วโมง นาที วินาที มิลลิวนาที ไมโครวินาที print(nowLocal.difference(nowUtc)); // -7:00:00.000000 // ค่าติดลบ ค่าเวลาที่มาเทียบ เกิดขึ้นทีหลัง // นั่นคือเวลาที่ UTC ช้ากว่าที่ไทย 7 ชม. // เราลองสลับตำแหน่ง print(nowUtc.difference(nowLocal)); // 7:00:00.000000 // เวลาที่มาเทียบเกิดขึ้นก่อน // นั่นคือเวลาที่ไทย เร็วกว่าที่ UTC 7 ชม. // เราสามารถสร้างตัวแปรมาเก็บค่าความต่างของเวลา แล้วเลือกแสดงเฉพาะ // ที่ต้องการได้ โดยค่ามากสุดจะอยู่ที่หน่วยวันที่ var difference = nowLocal.difference(nowUtc); print(difference); // -7:00:00.000000 print(difference.runtimeType); // Duration print(difference.inDays); // 0 = ต่างกัน 0 วัน print(difference.inHours); // -7 หมายถึง ต่างกัน 7 ชม. // เราสามารถเพิ่ม / ลบวันที่ และเวลาได้โดยใช้คำสั่ง add() กับ subtract() // ซึ่งจะเพิ่มเป็น Duration object กำหนด map key กับ value ที่ต้องการ // เช่น Duration(days: 366) หรือ Duration(days: 1, hours: 1) // ตัวอย่างบวกอีก 7 วันข้างหน้า และ ลบ 24 ชั่วโมงที่ผ่านมา var nextFriday = nowLocal.add(Duration(days:7)); var past24 = nowLocal.subtract(Duration(hours:24)); print(nowLocal); // 2019-11-29 23:30:30.000 print(nextFriday); // 2019-12-06 23:30:30.000 วันศุกร์หน้าคือวันที่ 6 print(past24); // 2019-11-28 23:30:30.000 เมื่อวานเวลาเดียวกัน // เราสามารถสร้าง DateTime object จาก String ที่เป็นรูปแบบวันที่และเวลา // โดยใช้คำสั่ง parse() เช่น var fatherDay = DateTime.parse("2019-12-05"); print(fatherDay); // 2019-12-05 00:00:00.000 // รูปแบบวันที่ที่รองรับบางส่วน เช่น /* "2019-02-29 23:30:00" "2019-02-29 23:30:00.123456z" "2019-02-29 23:30:00,123456z" "20191129 23:30:00" "20191129T233000" "20191129" */ }
เนื้อหาเกี่ยวกับ core library บางส่วนเบื้องต้น ก็จะประมาณนี้ หากมีรายละเอียดเพิ่มเติม จะนำมาอัพเดท อธิบายเพิ่มเติมต่อไป