ความยากเมื่อสร้างโครงสร้างข้อมูลแบบซ้อน


14

ในขณะที่พยายามสร้างข้อความ JSON สำหรับ API ฉันพบว่าตัวเองกำลังพยายามทำสิ่งที่ฉันคิดว่าจะง่าย ฉันต้องการสร้างข้อความดังต่อไปนี้:

{ "list": [ { "foo": 1, "bar": 2 } ] }

อย่างไรก็ตามความพยายามครั้งแรกของฉันไม่ทำงาน:

say to-json { foo => [ { a => 1, b => 2 } ] };
# {"foo":[{"a":1},{"b":2}]}

การพยายามลดความซับซ้อนของสิ่งต่าง ๆ ทำให้ฉันสับสนมากขึ้น:

say { foo => [ { a => 1 } ] };
# {foo => [a => 1]}
# Note that this is not JSON, but I expected to see curly braces

จากนั้นฉันพยายามใช้ตัวแปรชั่วคราวและใช้งานได้:

my @list = { a => 1 };
say to-json { foo => @list };
# {"foo":[{"a":1}]}

my %hash = ( a => 1 );
say to-json { foo => [ %hash ] };
# {"foo":[{"a":1}]}

เกิดอะไรขึ้นที่นี่?

และมีวิธีที่ฉันสามารถบรรลุผลลัพธ์ที่ต้องการโดยไม่มีตัวแปรชั่วคราวพิเศษหรือไม่?


1
say to-json { foo => [ { a => 1 } ] };สิ่งที่ควรจะเอาท์พุทเหมือนไม่{"foo":[{"a":1}]} {"foo":["a":1]}หลังเป็นตัวพิมพ์ผิดใช่มั้ย ถ้าไม่say $*PERL.compiler.version;พูดอะไร
raiph

หืมใช่แล้วคุณพูดถูก ฉันเดาว่าฉันทำสิ่งผิดพลาดเมื่อฉันพยายามทำสิ่งต่าง ๆ แม้กระทั่งsay to-json { foo => [ a => 1 ] }ผลลัพธ์{"foo":[{"a":1}]}ดังนั้นใครจะรู้สิ่งที่ฉันพิมพ์เมื่อฉันได้รับสิ่งนั้นถ้าฉันเคยทำ ความผิดฉันเอง!
jja

คำตอบ:


17

คุณได้ค้นพบกฎอาร์กิวเมนต์เดียว สิ่งปลูกสร้างจำนวนมากใน Raku จะทำซ้ำอาร์กิวเมนต์ที่มีให้ ซึ่งรวมถึงผู้[...]แต่งอาเรย์ นี่คือเหตุผลที่เมื่อเราพูดว่า:

say [1..10];

เราได้รับอาร์เรย์ที่มี 10 องค์ประกอบไม่ใช่ 1 อย่างไรก็ตามมันก็หมายความว่า:

say [[1,2]];

ซ้ำค่า[1,2]และดังนั้นจึงส่งผลให้[1,2]- ราวกับว่าอาร์เรย์ภายในไม่ได้อยู่ที่นั่น A Hashซ้ำกับคู่ของมันดังนี้:

{ foo => [ { a => 1, b => 2 } ] }

ผลิตจริง:

{ foo => [ a => 1, b => 2 ] }

นั่นคืออาร์เรย์มีคู่ จากนั้น JSON serializer แล้วซีเรียลไลซ์แต่ละคู่เป็นวัตถุองค์ประกอบเดียว

การแก้ปัญหาคือการผลิตซ้ำองค์ประกอบเดียว ,ผู้ประกอบการมัดเป็นสิ่งที่สร้างรายการดังนั้นเราจึงสามารถใช้ที่:

say to-json { foo => [ { a => 1, b => 2 }, ] };
#                        note the , here ^

จากนั้นอาร์กิวเมนต์เดียวที่จะวนซ้ำเป็นรายการ 1 องค์ประกอบพร้อมแฮชและคุณจะได้รับผลลัพธ์ตามที่คุณต้องการ

วิธีที่ง่ายต่อการจดจำ: ใช้เครื่องหมายจุลภาคต่อท้ายทุกครั้งเมื่อระบุค่าของรายการอาร์เรย์หรือแฮชแม้จะมีรายการองค์ประกอบเดียวเว้นแต่ว่าคุณจะระบุรายการที่สามารถทำซ้ำได้


2
อีกวิธีคือการลงรายละเอียดในสเกลาร์: {foo => [$ {a => 1, b => 2}]}}
jakar
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.