Ep 5 : LINQ

LINQ (Language Integrated Query) เป็นฟีเจอร์ของ C# ที่ช่วยให้เราสามารถเขียนโค้ดที่จัดการกับข้อมูลในรูปแบบของ Collection, Database, XML, หรือ Object ได้อย่างมีประสิทธิภาพและอ่านง่ายขึ้น

โดย LINQ มีความสามารถที่ช่วยให้เราสามารถ กรอง (Filter), จัดเรียง (Sort), รวม (Aggregate), และเปลี่ยนแปลง (Transform) ข้อมูล ได้ในรูปแบบที่กระชับและเข้าใจง่ายกว่าการใช้ foreach และ for ปกติ

แต่อย่างไรก็ดี ควรใช้ LINQ อย่างระมัดระวัง เนื่องจากบางคำสั่งอาจมีผลต่อ Performance โดยเฉพาะบนมือถือ เช่น คำสั่งที่ใช้การจัดเรียง (OrderBy) หรือคำสั่งที่สร้างอ็อบเจกต์ใหม่บ่อย ๆ เช่น การ Select หรือ Where บน List ขนาดใหญ่

  1. Query Syntax (สไตล์คล้าย SQL)
  2. Method Syntax (ใช้ Lambda Expression)
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public class LinqDemo : MonoBehaviour
{
    void Start()
    {
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 };
        // วิธีที่ 1 Query Syntax
        var evenNumbersQuery = from num in numbers
                               where num % 2 == 0
                               select num;

        // วิธีที่ 2 Method Syntax (Lambda Expression)
        var evenNumbersMethod = numbers.Where(num => num % 2 == 0);

        // แสดงผลลัพธ์จากวิธีที่ 1
        Debug.Log("Query Syntax: " + string.Join(", ", evenNumbersQuery));
        // แสดงผลลัพธ์จากวิธีที่ 2
        Debug.Log("Method Syntax: " + string.Join(", ", evenNumbersMethod));
    }
}

Where() → คัดกรองข้อมูลตามเงื่อนไข
FirstOrDefault() / First() → คืนค่าตัวแรกที่ตรงกับเงื่อนไข (ถ้าไม่มีค่า First() จะ Error แต่ FirstOrDefault() จะคืนค่า null หรือค่าเริ่มต้น)
LastOrDefault() / Last() → คืนค่าตัวสุดท้ายที่ตรงกับเงื่อนไข
SingleOrDefault() / Single() → คืนค่าตัวเดียวเท่านั้น ถ้าพบมากกว่าหนึ่งตัวจะ Error

List<int> numbers = new List<int> { 10, 20, 30, 40, 50 };

var result = numbers.Where(n => n > 25).ToList(); 
int firstNumber = numbers.FirstOrDefault(n => n > 25); 
int lastNumber = numbers.LastOrDefault(n => n > 25);
int singleNumber = numbers.SingleOrDefault(n => n == 40); 

Debug.Log( reult );
Debug.Log( firstNumber );
Debug.Log( lastNumber );
Debug.Log( singleNumber );

OrderBy() → เรียงลำดับจากน้อยไปมาก
OrderByDescending() → เรียงลำดับจากมากไปน้อย

List<int> numbers = new List<int> { 5, 2, 8, 1, 9, 11, 3, 4, 7 };
var sortedNumbers = numbers.OrderBy(n => n).ToList(); 
var sortedDescNumbers = numbers.OrderByDescending(n => n).ToList(); 

Debug.Log( startedNumbers);
Debug.Log( startedDescNumbers);

Select() → ใช้สำหรับแปลงค่าหรือเลือกเฉพาะบางฟิลด์
SelectMany() → ใช้เมื่อแต่ละรายการมี List ซ้อนอยู่ภายใน

List<string> names = new List<string> { "Lisa", "Simone", "Lara" };
var upperNames = names.Select(n => n.ToUpper()).ToList(); 

Debug.Log( names );
Debug.Log( upperNames);

Sum() → ผลรวมของค่าทั้งหมด
Average() → ค่าเฉลี่ย
Count() → จำนวนข้อมูล
Max() / Min() → ค่าสูงสุด/ต่ำสุด

List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 10, 20, 30, 40, 50, 100, 200, 300, 400, 500 };
int sum = numbers.Sum();
double avg = numbers.Average(); 
int count = numbers.Count(); 
int max = numbers.Max(); 
int min = numbers.Min(); 

Debug.Log( sum );
Debug.Log(avg);
Debug.Log(count);
Debug.Log(min);
Dbug.Log(max);

Any() → คืนค่า true ถ้ามีอย่างน้อยหนึ่งรายการที่ตรงเงื่อนไข
All() → คืนค่า true ถ้าทุกตัวตรงเงื่อนไข

List<int> numbers = new List<int> { 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60 };
bool hasEven = numbers.Any(n => n % 2 == 0); 
bool allGreaterThanZero = numbers.All(n => n > 0); 

Debug.Log( hasEven );
Debug.Log( allGreaterThanZero);

สามารถใช้ LINQ เพื่อค้นหาและจัดการ GameObject ได้ดังตัวอย่างต่อไปนี้เป็นการปิดการทำงานศัตรูที่มี HP น้อยกว่า 10

using System.Linq;
using UnityEngine;

public class LinqWithGameObjects : MonoBehaviour
{
    void Start()
    {
        GameObject[] enemies = GameObject.FindGameObjectsWithTag("Enemy");

        // หาศัตรูที่มีค่า HP น้อยกว่า 10
        var weakEnemies = enemies
            .Where(e => e.GetComponent<Enemy>().health < 10)
            .ToList();

        // ปิดการใช้งานศัตรูที่อ่อนแอทั้งหมด
        weakEnemies.ForEach(e => e.SetActive(false));
    }
}
  • LINQ ช่วยให้เขียนโค้ดได้กระชับและอ่านง่ายขึ้น
  • สามารถใช้ Where(), Select(), OrderBy(), Sum(), Any() และอื่นๆ กับข้อมูลต่างๆ ได้
  • ใช้ LINQ กับ GameObject ได้ แต่ต้องระวัง Performance
  • ใช้กับข้อมูลขนาดเล็ก เช่น ค้นหา GameObject, คำนวณค่าจาก List
  • หลีกเลี่ยงการใช้ LINQ ใน Update() หรือ FixedUpdate() หรือ Loop ขนาดใหญ่ (มีการวนรอบหลายรอบมาก ๆ) เพราะอาจเกิด Garbage Collection และทำให้เกมกระตุก

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *