Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

วิธีสร้าง Array ด้วยค่าซ้ำที่ไม่ใช่ Default ใน C#

Enumerable.Repeat() - สร้าง Sequence ค่าซ้ำ

Enumerable.Repeat<T>(element, count) (ใน System.Linq) สร้าง IEnumerable<T> ที่มีค่า element ซ้ำ count ครั้ง

ตัวอย่างพื้นฐาน

using System;
using System.Linq;

class Program
{
    static void Main()
    {
        // สร้าง IEnumerable ค่า 10 ซ้ำ 5 ครั้ง
        var values = Enumerable.Repeat(10, 5);
        
        foreach (var item in values)
        {
            Console.WriteLine(item);
        }
    }
}

ผลลัพธ์:

10
10
10
10
10

แปลงเป็น Array (.ToArray())

using System;
using System.Linq;

class Program
{
    static void Main()
    {
        // สร้าง int[] โดยตรง
        int[] values = Enumerable.Repeat(10, 5).ToArray();
        
        // ตรวจสอบ Type
        Console.WriteLine($"Type: {values.GetType().Name}");  // Int32[]
        Console.WriteLine($"Length: {values.Length}");  // 5
        
        foreach (var item in values)
        {
            Console.WriteLine(item);
        }
    }
}

กรณีใช้งานจริง

1. Initialize Array ด้วยค่า Default ที่ไม่ใช่ 0/false/null


// แทน new int[100] ที่ได้ 0 ทุกตัว
int[] initializedToFive = Enumerable.Repeat(5, 100).ToArray();
bool[] initializedToTrue = Enumerable.Repeat(true, 50).ToArray();
string[] initializedToHello = Enumerable.Repeat("Hello", 10).ToArray();

2. สร้าง Test Data


var testUsers = Enumerable.Repeat(new User { Name = "Test", Role = "User" }, 100).ToList();
// ⚠️ ข้อควรระวัง: Object เดียวกันทุกตัว (Reference เหมือนกัน)!
// ต้องใช้ Select แทนถ้าต้องการ Object แยกกัน:
var testUsers2 = Enumerable.Range(1, 100).Select(i => new User { Name = $"Test{i}", Role = "User" }).ToList();

3. Padding / Fill Array


int[] original = { 1, 2, 3 };
int[] padded = original.Concat(Enumerable.Repeat(0, 10 - original.Length)).ToArray();
// Result: [1, 2, 3, 0, 0, 0, 0, 0, 0, 0]

4. สร้าง Matrix / 2D Array


// 3x3 Matrix filled with -1
int[][] matrix = Enumerable.Repeat(0, 3)
    .Select(_ => Enumerable.Repeat(-1, 3).ToArray())
    .ToArray();

Repeat vs Range

เมธอดใช้สำหรับตัวอย่าง
Repeat(value, count)ค่าเดิมซ้ำหลายครั้งRepeat(7, 5) → 7,7,7,7,7
Range(start, count)ลำดับตัวเลขRange(1, 5) → 1,2,3,4,5

Reference Type Warning ⚠️


class Person { public string Name; }

// ❌ ผิด: Object เดียวกันซ้ำ 3 ตัว (Reference เหมือนกัน)
var people = Enumerable.Repeat(new Person { Name = "A" }, 3).ToList();
people[0].Name = "B";
Console.WriteLine(people[1].Name);  // "B" - เปลี่ยนไปด้วย!

// ✅ ถูกต้อง: สร้าง Object ใหม่ทุกครั้ง
var people2 = Enumerable.Range(0, 3).Select(_ => new Person { Name = "A" }).ToList();
people2[0].Name = "B";
Console.WriteLine(people2[1].Name);  // "A" - ไม่เปลี่ยน

Performance Note

  • Enumerable.Repeat ใช้ Deferred Execution (Lazy) - ไม่สร้าง Array จนกว่าจะ Enumerate (.ToArray(), .ToList(), foreach)
  • สำหรับ Array ขนาดใหญ่ ควร Pre-allocate: new T[count] แล้ว Fill ด้วย Array.Fill() (.NET 5+)

.NET 5+ Array.Fill()


// เร็วกว่า Enumerable.Repeat().ToArray() สำหรับ Array ขนาดใหญ่
int[] array = new int[1_000_000];
Array.Fill(array, 42);  // Fill ทั้ง Array ด้วย 42

// หรือ Fill บางส่วน
Array.Fill(array, 99, 100, 50);  // Index 100-149 = 99

สรุป

  • Enumerable.Repeat(value, count) - สร้าง Sequence ค่าซ้ำ (Lazy)
  • .ToArray() / .ToList() - Materialize เป็น Array/List
  • ระวัง Reference Type - จะได้ Object เดียวกันซ้ำ (ใช้ Select แทน)
  • .NET 5+: ใช้ Array.Fill() สำหรับ Performance Critical
  • เหมาะสำหรับ: Test Data, Padding, Initialization, Matrix