นับเทียบกับความยาวกับขนาดในคอลเลกชัน


167

จากการใช้ภาษาโปรแกรมและไลบรารีจำนวนมากฉันสังเกตเห็นคำศัพท์ต่าง ๆ ที่ใช้สำหรับองค์ประกอบทั้งหมดในคอลเลกชัน

ที่พบมากที่สุดดูเหมือนจะเป็นlength, และcountsize

เช่น.

array.length
vector.size()
collection.count

มีคำที่ต้องการใช้ไหม มันขึ้นอยู่กับประเภทของคอลเลกชันหรือไม่? กล่าวคือ ไม่แน่นอน / ไม่เปลี่ยนรูป

มีการตั้งค่าสำหรับมันเป็นคุณสมบัติแทนวิธีการหรือไม่?


และมีList.Capacityคุณสมบัติเช่นกันใน C #
RBT

ฉันหวังว่าภาษาใหม่จะหลีกเลี่ยงคำที่ไม่ชัดเจน
Nikolay Klimchuk

คำตอบ:


231

Length() มีแนวโน้มที่จะอ้างถึงองค์ประกอบที่อยู่ติดกัน - สตริงมีความยาวเช่น

Count() มีแนวโน้มที่จะอ้างถึงจำนวนขององค์ประกอบในคอลเลกชันโยก

Size() มีแนวโน้มที่จะอ้างถึงขนาดของคอลเลกชันซึ่งมักจะแตกต่างจากความยาวในกรณีเช่นเวกเตอร์ (หรือสตริง) อาจมี 10 ตัวอักษรในสตริง แต่การจัดเก็บถูกสงวนไว้สำหรับ 20 มันอาจหมายถึงจำนวน องค์ประกอบ - ตรวจสอบแหล่งที่มา / เอกสาร

Capacity()- ใช้เพื่ออ้างถึงพื้นที่ที่ได้รับการจัดสรรโดยเฉพาะและไม่ใช่จำนวนองค์ประกอบที่ถูกต้อง หากประเภทมีทั้ง "ความจุ" และ "ขนาด" ที่กำหนดไว้แล้ว "ขนาด" มักจะหมายถึงจำนวนองค์ประกอบที่แท้จริง

ฉันคิดว่าประเด็นหลักอยู่ที่ภาษามนุษย์และสำนวนขนาดของสตริงดูเหมือนไม่ชัดเจนมากในขณะที่ความยาวของฉากนั้นสร้างความสับสนอย่างเท่าเทียมกันแม้ว่าพวกเขาอาจจะใช้เพื่ออ้างถึงสิ่งเดียวกัน (จำนวนองค์ประกอบ ) ในการรวบรวมข้อมูล


5
ดังนั้น "คอลเลกชันโยก" คืออะไร? ฉันไม่เห็นความแตกต่างระหว่างขนาดและนับที่นี่
Sophie Alpert

32
@ben: ขนาด = ช่องที่มี, จำนวน = องค์ประกอบที่เกิดขึ้นจริง ขนาด == นับเมื่อคอลเลกชันเต็ม
สตีเว่น Evers

8
downvoting เพราะsize()หมายถึงจำนวนขององค์ประกอบในเวกเตอร์ที่ไม่มันcapacity()... อย่างน้อยใน C ++ ซึ่งผมคิดว่าเป็นผู้ริเริ่มของvectorS กับsizes
Dave Abrahams

10
@DaveAbrahams - ฉันไม่เคยพูดแบบนั้นมาก่อน อ่านอีกครั้ง ฉันบอกว่ามัน "มีแนวโน้มที่จะอ้างถึง" ฉันไม่เคยแม้แต่จะพยายามที่จะทำให้คำสั่งเฉพาะที่ใช้อย่างเท่าเทียมกันกับการเปลี่ยนแปลงทั้งหมดของคอลเลกชันทุกชั้นในทุกภาษา
gbjbaanb

2
@SnOrfus ฉันคิดว่าคุณได้เข้าสู่อาณาจักรของ "ความสามารถ" ที่นั่น std::vector(C ++) เช่นใช้ "ความจุ" และ "ขนาด" โดยที่คุณใช้ "ขนาด" และ "นับ" ตามลำดับ ที่จริงแล้วทุกอย่างในการstd::ใช้ "ขนาด" สำหรับการนับองค์ประกอบปัจจุบันแม้std::string(ซึ่งให้ "ขนาด" สำหรับความเข้ากันได้ของแม่แบบและ "ความยาว" ที่เหมือนกันอย่างสมบูรณ์สำหรับ ... ความสะดวกสบายของมนุษย์ฉันเดา)
Jason C

28

FWIW (และใกล้จะไม่มีอะไรเลย) ฉันชอบ 'นับ' เพราะดูเหมือนว่าจะบ่งบอกว่ามันจะส่งคืนจำนวนองค์ประกอบ / รายการในคอลเลกชันค่อนข้างไม่น่าสงสัย

เมื่อต้องเผชิญกับคำว่า 'ความยาว' หรือ 'ขนาด' ฉันมักจะสงสัยว่าสักครู่ (หรือแม้กระทั่งถูกบังคับให้อ่านเอกสารอีกครั้ง) ว่าสิ่งที่แช่งกำลังจะบอกฉันว่ามีองค์ประกอบหลายอย่างในการ colection หรือไม่ ไบต์จำนวนมากที่คอลเลกชันใช้งานอยู่ นี่เป็นเรื่องจริงโดยเฉพาะอย่างยิ่งสำหรับคอลเลกชันที่ตั้งใจจะให้เหมือนอาร์เรย์หรือสตริง

แต่ไม่มีใครรับผิดชอบหลักการตั้งชื่อที่ใช้โดยกรอบมาตรฐาน / Java, BCL / .Net หรือ C / C ++ รำคาญที่จะถามฉันดังนั้นคุณก็ติดอยู่กับอะไรก็ตามที่เกิดขึ้น

ถ้าฉันฉลาดกว่าฉันและมีชื่อว่า Bjarne พวกคุณทุกคนอาจรอดพ้นจากความทุกข์ยาก ...

แน่นอนว่าในโลกแห่งความเป็นจริงคุณควรพยายามทำตามแผนการตั้งชื่อที่ใช้โดยภาษา / แพลตฟอร์มที่คุณใช้ (เช่น. size()ใน C ++) ไม่ใช่ว่าสิ่งนี้ดูเหมือนจะช่วยให้คุณมีArray.Lengthภาวะที่กลืนไม่เข้าคายไม่ออกของคุณ


16
ในขณะที่ความยาวและขนาดเป็นคำนาม Count ยังเป็นคำกริยาดังนั้นจึงสามารถตีความได้ว่าเป็นการนับที่รันไทม์ (O (n)) เทียบกับการค้นหาค่า (O (1))
mbx

อันที่จริงที่ว่าวิธีการที่จะนำมาใช้ใน LINQ: Enumerable.Count
เอ็ดเวิร์ด Brey

11

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

length()หมายความว่าองค์ประกอบมีความยาว สตริงมีความยาว คุณพูดว่า "สตริงมีความยาว 20 ตัวอักษร" ใช่ไหม ดังนั้นมันจึงมีความยาว

size()หมายความว่าองค์ประกอบมีขนาด เช่นไฟล์มีขนาด คุณพูดว่า "ไฟล์นี้มีขนาด 2 MB" ใช่ไหม ดังนั้นจึงมีขนาด

ที่กล่าวว่าสตริงยังสามารถมีขนาด แต่ฉันคาดหวังอย่างอื่นที่นี่ เช่นสตริง UTF-16 อาจมีความยาว 100 อักขระ แต่เนื่องจากอักขระทุกตัวประกอบด้วยสองไบต์ฉันจึงคาดหวังว่าขนาดจะเท่ากับ 200

count()มันผิดปกติมาก Objective-C ใช้การนับจำนวนองค์ประกอบในอาร์เรย์ หนึ่งอาจโต้แย้งว่าอาร์เรย์มีความยาว (เช่นใน Java) มีขนาด (ในภาษาอื่น ๆ ส่วนใหญ่) หรือมีการนับ อย่างไรก็ตามขนาดอาจเป็นขนาดเป็นไบต์อีกครั้ง (หากรายการอาร์เรย์เป็น 32 บิต int แต่ละรายการคือ 4 ไบต์) และความยาว ... ฉันจะไม่พูดว่า "อาร์เรย์ยาว 20 องค์ประกอบยาว" ซึ่งฟังดูค่อนข้างแปลก ผม. ฉันจะบอกว่า "อาร์เรย์มี 20 องค์ประกอบ" ฉันไม่แน่ใจว่าการนับเป็นการแสดงออกที่ดีมาก แต่ฉันคิดว่าการนับอยู่ที่นี่เป็นแบบสั้น ๆelementCount()และนั่นทำให้รู้สึกเหมาะสมกับอาร์เรย์มากกว่าความยาว () หรือขนาด ()

หากคุณสร้างออบเจ็กต์ / องค์ประกอบของตนเองในภาษาการเขียนโปรแกรมวิธีที่ดีที่สุดคือใช้องค์ประกอบอื่น ๆ ที่คล้ายกันเนื่องจากโปรแกรมเมอร์ใช้เพื่อเข้าถึงคุณสมบัติที่ต้องการโดยใช้คำนั้น


การติดตามสตริงของคุณคล้ายคลึงกันไฟล์จะต้องมีlengthแต่sizesคลังเก็บข้อมูลที่แตกต่างกันอาจใช้ที่แตกต่างกันในการจัดเก็บข้อมูล Java ยังคิดเช่นนั้นในjava.io.File # length ()แต่ดูเหมือนว่าคนอื่น ๆ ในโลกไม่เห็นด้วย
Ivan Balashov

1
@IvanBalashov ฉันไม่เคยใช้ "ความยาวของไฟล์" ในการสนทนารายวันสำหรับฉันไฟล์มีความยาวไม่เท่าขนาดและนั่นก็เป็นสิ่งที่ฉันเขียนไว้ในคำตอบของฉัน เมื่อใดก็ตามที่เรากำลังพูดถึงไบต์ดิบเรากำลังพูดถึงขนาด IMHO และไฟล์ที่ไม่มีเนื้อหาที่ใกล้ชิดเป็นเพียงไบต์จำนวนมาก ความยาวมักจะไม่ใช้สำหรับการแสดงจำนวนไบต์ แต่เป็นการแสดงการสะสมขององค์ประกอบที่รวมกัน (ไบต์ไม่ได้เป็นองค์ประกอบของฉันยิ่งสร้างบล็อคให้มีองค์ประกอบมากขึ้นและพวกเขาก็ไม่ได้ "รวมเข้าด้วยกัน")
Mecki

4

นับฉันคิดว่าเป็นคำที่ชัดเจนที่สุดที่จะใช้หากคุณกำลังมองหาจำนวนรายการในคอลเลกชัน นั่นควรจะชัดเจนสำหรับโปรแกรมเมอร์ใหม่ที่ยังไม่ได้แนบกับภาษาใดภาษาหนึ่งโดยเฉพาะ

และควรเป็นคุณสมบัติอย่างที่เป็นอยู่นั่นคือคำอธิบาย (หรือที่เรียกว่าคุณสมบัติ) ของการรวบรวม วิธีหนึ่งบ่งบอกว่ามันต้องทำอะไรบางอย่างกับคอลเล็กชั่นเพื่อรับจำนวนไอเท็มและดูเหมือนว่าไม่ได้ใช้งานง่าย


3

อืม ... ฉันจะไม่ใช้ขนาด เนื่องจากอาจสับสนกับขนาดเป็นไบต์ ความยาว - สามารถใช้ความรู้สึกกับอาร์เรย์ได้นานเท่าที่ควรจะใช้หน่วยความจำไบต์ต่อเนื่อง แม้ว่า ... ความยาว ... ในอะไร การนับมีความชัดเจน มีกี่องค์ประกอบ ฉันจะใช้การนับ

เกี่ยวกับคุณสมบัติ / วิธีการฉันจะใช้คุณสมบัติเพื่อทำเครื่องหมายว่ารวดเร็วและวิธีการทำเครื่องหมายนั้นช้า

และที่สำคัญที่สุด - ฉันจะยึดมาตรฐานของภาษา / ไลบรารีที่คุณใช้อยู่


ดังนั้นข้อมูลเกี่ยวกับ DataBlock เพียงไม่กี่ไบต์ มันมีความยาวหรือมีขนาดหรือไม่?
Mecki

2

กำลังเพิ่มคำตอบของ @ gbjbaanb ...

หาก "คุณสมบัติ" แสดงถึงการเข้าถึงค่าสาธารณะฉันจะบอกว่า "วิธีการ" เป็นที่ต้องการเพียงเพื่อให้การห่อหุ้มและเพื่อซ่อนการใช้งาน

คุณอาจจะเปลี่ยนคุณทราบเกี่ยวกับวิธีการองค์ประกอบหรือว่าคุณยืนยันว่าcount countหากเป็นคุณสมบัติคุณจะติดอยู่ - หากได้รับการแก้ไขโดยวิธีการคุณสามารถเปลี่ยนการใช้งานพื้นฐานโดยไม่ส่งผลกระทบต่อผู้ใช้คอลเลกชัน


ทำไมคุณถึง“ ติด” ถ้ามันถูกเปิดเผยเป็นคุณสมบัติ? คุณสมบัติมีการใช้งานพื้นฐานที่สามารถเปลี่ยนแปลงได้ง่ายเช่นกันโดยไม่ต้องทำลายส่วนต่อประสาน ในความเป็นจริงภาษาส่วนใหญ่จะนำคุณสมบัติไปใช้เนื่องจากคอมไพเลอร์สร้างวิธีรับ / ตั้งค่าอยู่แล้ว ... คุณไม่สามารถเรียกมันได้โดยตรง
Scott Dorman

คุณหมายถึง "ภาษาส่วนใหญ่" ใด C, C ++, Java (เพียงชื่อไม่กี่) อย่าทำเช่นนี้ ฉันรู้ว่าทับทิมและ Groovy โปรดทราบว่าฉันเริ่มคำตอบด้วยเช่นกัน: "หาก 'ทรัพย์สิน' มีความหมาย ... " ทำไมถึงติดอยู่ หากอินเทอร์เฟซกับคลาสเปลี่ยนแปลงลูกค้าต้องเปลี่ยน (โดยทั่วไปจะพูด)
Ken Gentle

1

ใน Elixir มีรูปแบบการตั้งชื่อที่ชัดเจนที่เกี่ยวข้องกับมันข้ามประเภทในภาษา

เมื่อ“ นับ” จำนวนองค์ประกอบในโครงสร้างข้อมูล Elixir ก็ปฏิบัติตามกฎง่าย ๆ : ฟังก์ชั่นนี้มีชื่อsizeถ้าการดำเนินการอยู่ในช่วงเวลาคงที่ (เช่นค่าถูกคำนวณล่วงหน้า) หรือ lengthการดำเนินการเป็นเชิงเส้น (เช่นการคำนวณ ความยาวจะช้าลงเมื่ออินพุตเพิ่มขึ้น)


0

สำหรับฉันมันเหมือนกับถามว่า "foreach" ดีกว่า "สำหรับแต่ละ" หรือไม่ มันขึ้นอยู่กับภาษา / กรอบงาน


แล้วมันมีความสำคัญอะไร? การเปลี่ยนแปลงอะไร พวกเราทุกคนจะเขียนอีเมลที่โกรธแค้นไปยังกลุ่มคน Java เพื่อเลือกสองคนและไม่สอดคล้องกันหรือไม่?
S.Lott

1
นั่นคือประเด็นของฉัน ทำไมต้องสงสัยซึ่งดีกว่า มันเป็นสิ่งที่มันเป็น.
EBGreen

0

ฉันจะบอกว่ามันขึ้นอยู่กับโดยเฉพาะอย่างยิ่งภาษาที่คุณกำลังใช้และการเรียน ตัวอย่างเช่นใน c # หากคุณใช้ Array คุณมีProperty Length ถ้าคุณมีบางสิ่งที่สืบทอดมาจาก IEnumerable คุณมีส่วนขยายMethod Count () แต่มันไม่เร็ว และถ้าคุณสืบทอดจาก ICollection คุณจะมีจำนวนคุณสมบัติ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.