Ruby :: Building a string from parts

Posted by PunNeng, Sun Dec 17 14:25:00 UTC 2006

การสร้าง string จาก string ย่อยๆ อีกที มี 2 วิธีที่แนะนำ วิธีที่ง่ายที่สุดคือการเริ่มต้นด้วย string ว่างๆ แล้วทำการใส่ string ย่อยๆ เข้าไปด้วย "<<" (ทำหน้าที่เหมือนๆ กับ concat หรือ push ครับ)

hash = { "key1" => "val1", "key2" => "val2" }
string = ""
hash.each { |k,v| string << "#{k} is #{v}\n" }
puts string
# key1 is val1
# key2 is val2

มีอีกวิธี แต่มันอ่านยากหน่อย

string = ""
hash.each { |k,v| string << << " is " << v << "\n" }

ถ้าเราเก็บไว้ในรูปของ array เราสามารถใช้ Array#join ได้

puts hash.key.join("\n") + "\n"
# key1
# key2

ในภาษาอย่าง Python หรือ Java การสร้าง string โดยเริ่มจาก string เปล่าๆ แล้วค่อยต่อ string ไปทีหลัง มันไม่ค่อยดี ภาษาพวกนี้มันกลายร่างไม่ได้ ดังนั้น การที่จะต่อ strinig เข้าไปใหม่ มันก็ต้องการสร้าง string ใหม่มาอีกตัว การทำแบบนี้หลายๆ ครั้ง มันก็ย่อมใช้หน่วยความจำและเวลาอย่างสิ้นเปลือง

วิธีการที่เหมาะสมสำหรับภาษาพวกนี้ คือเอา string ตัวย่อยๆ ใส่ๆเข้าไปใน array หรือใน data structure อื่นๆ ที่มันสามารถขยายตัวมันเองได้อัติโนมัติ ดีกว่าที่จะไป new Object ขึ้นมาใหม่ จริงๆ แล้วขั้นตอนการกลายร่าง ใน Java เราสามารถใช้ StringBuffer class ช่วยได้ครับ(ความหมายของคำว่า "กลายร่าง" ดูได้ที่นี่)

ใน Ruby ตัว string มันกลายร่างได้ เหมือนๆ กับ array ย่อขยายได้ โดยที่ไม่ต้องใช้เวลากับหน่วยความจำมาก ลองดู สองตัวอย่างนี้

str << 'a' + 'b' 
str << "#{var1} #{var2}"

ก่อนที่มันจะใส่ string เข้าไปใน str มันยังต้องสร้าง string มาอีกก้อน และ string ก้อนนั้น เป็นก้อนที่ใหญ่ แต่ถ้าเราทำแบบนี้

str << var1 << ' ' << var2

string ตัวที่ถูกสร้างใหม่ มีแค่ ' ' เท่านี้เอง

นิดนึงสำหรับ Array#join มันไม่ทำการเพิ่มอักขระเข้าไปหลัง element ของ array ทุกตัว แต่มันจะแทรกเข้าไประหว่าง element สองตัวของ array เช่น

data = ['1', '2', '3']
s = ''
data.each { |x| s << x << ' and a ' )
s                            # "1 and a 2 and a 3 and a"
data.join('and a ')          # "1 and a 2 and a 3"

ถ้าจะจำลองการทำงานของ Array#join ผ่าน iterator เราสามารถใช้ Enumerable#each_with_index ช่วย แล้วเอาตัวที่จะมาแทรก ออกตอนท้ายได้ ดังนี้

s = ""
data.each_with_index { |x, i| s << x; s << "|" if i < data.length -1 }
s                             # => "1|2|3"

แก้ไขล่าสุด วันที่ 21 กรกฏาคม 2550 เวลา 0.14 น.

Filed Under: Ruby | Tags: howto ruby string

Comments

Have your say

A name is required. You may use HTML in your comments.




codegent: we're hiring