อิกัวนาต้นฉบับตัดริบบิ้นข้อมูลตรงหมุดเดี่ยวและเก็บถาดว่างไว้ตรงตำแหน่งเดิม

Zig splitScalar: เก็บช่องว่างใน CSV เล็ก ๆ ไม่ให้ข้อมูลเลื่อน

พี่โชว์Engineering

ข้อมูลคั่นด้วย comma บางชุดให้ความหมายกับช่องว่าง เช่น room,,ready หมายถึง field กลางไม่มีค่า หากใช้ tokenizer ที่ข้ามช่องว่าง ตำแหน่งจะเลื่อน std.mem.splitScalar คืน field ว่างตามจริงและไม่ allocate สำเนาครับ

WHY: เก้าอี้ว่างก็ยังเป็นตำแหน่งหนึ่ง

เหมือนโต๊ะสามที่นั่ง แม้ที่กลางไม่มีคนนั่ง เราก็ไม่ควรเลื่อนคนที่สามมาเป็นคนที่สอง splitScalar เหมาะกับ schema ที่จำนวนและตำแหน่ง field สำคัญ ต่างจาก tokenizeScalar ซึ่งตั้งใจข้าม delimiter ซ้ำ

const std = @import("std");

fn parseThree(input: []const u8) ![3][]const u8 {
    var it = std.mem.splitScalar(u8, input, ',');
    const first = it.next() orelse return error.MissingField;
    const second = it.next() orelse return error.MissingField;
    const third = it.next() orelse return error.MissingField;
    if (it.next() != null) return error.TooManyFields;
    return .{ first, second, third };
}

test "split keeps an empty field" {
    const fields = try parseThree("room,,ready");
    try std.testing.expectEqualStrings("room", fields[0]);
    try std.testing.expectEqualStrings("", fields[1]);
    try std.testing.expectEqualStrings("ready", fields[2]);
    try std.testing.expectError(error.MissingField, parseThree("room,ready"));
    try std.testing.expectError(error.TooManyFields, parseThree("a,b,c,d"));
}

HOW: นี่ไม่ใช่ CSV parser เต็มรูปแบบ

ตัวอย่างใช้ delimiter หนึ่งไบต์และไม่รองรับ quoted field, comma ภายในข้อความ หรือ escape rule ของ CSV จริง หากรูปแบบข้อมูลอนุญาตสิ่งเหล่านั้น ให้ใช้ parser ที่เข้าใจมาตรฐานแทน อย่าค่อย ๆ เติมเงื่อนไขจนกลายเป็น parser ทำเองที่ไม่มี test ครบ

slice ที่ iterator คืนยังอ้าง input ต้นฉบับ จึงต้องรักษา buffer ไว้ตลอดช่วงใช้งาน กำหนดเพดานความยาว input และจำนวน field ก่อนนำไปสร้าง object เพื่อป้องกัน payload ใหญ่กินหน่วยความจำขั้นต่อไป

Recap

  • ใช้ splitScalar เมื่อ empty field มีความหมาย
  • ใช้ tokenizeScalar เมื่อ delimiter ซ้ำควรถูกข้าม
  • ตรวจจำนวน field ทั้งขาดและเกิน
  • อย่าใช้เป็น CSV parser ถ้ามี quote หรือ escape
  • รักษาอายุ input buffer ให้ยาวกว่า slices