รับรายการในรายการใน Scala หรือไม่


205

คุณจะได้รับเพียงแค่องค์ประกอบที่ดัชนีฉันจากรายการในสกาล่าในโลกได้อย่างไร

ฉันพยายามget(i)และ [i]- ไม่มีอะไรทำงาน Googling คืนค่าวิธีการ "ค้นหา" องค์ประกอบในรายการเท่านั้น แต่ฉันรู้ดัชนีขององค์ประกอบแล้ว!

นี่คือรหัสที่ไม่ได้รวบรวม:

def buildTree(data: List[Data2D]):Node ={
  if(data.length == 1){
      var point:Data2D = data[0]  //Nope - does not work

  }
  return null
}

การดูรายการ List APIไม่ได้ช่วยเพราะดวงตาของฉันเพิ่งผ่านไป


1
ดูเหมือนว่าdata.head จะทำงาน ... แต่ก็ยังให้องค์ประกอบแรกกับฉันเท่านั้นไม่ใช่ในรายการ
Andriy Drozdyuk

ใช้ลักษณะSeq นำไปใช้ (ดัชนี)หากคุณแน่ใจว่าดัชนีไม่อยู่นอกขอบเขต scala-lang.org/api/current/…
Beezer

data.drop (i) .head ใช้สำหรับเข้าถึงองค์ประกอบ i-th
Vinay

@Vinay นั่นเป็นการดำเนินการที่มีค่าใช้จ่ายสูง ดังนั้นเราควรหลีกเลี่ยง "ดรอป (i) .head"
Shubham Agrawal

คำตอบ:


305

ใช้วงเล็บ:

data(2)

แต่คุณไม่ต้องการทำรายการบ่อยนักเนื่องจากรายการที่ลิงก์ต้องใช้เวลาในการสำรวจ หากคุณต้องการจัดทำดัชนีลงในคอลเลกชันให้ใช้Vector(ไม่เปลี่ยนรูป) หรือArrayBuffer(ไม่แน่นอน) หรืออาจเป็นไปได้Array(ซึ่งเป็นเพียงอาร์เรย์ Java ยกเว้นคุณสร้างดัชนีลงในนั้นด้วย(i)แทนที่จะเป็น[i])


1
โดยทั่วไปฉันกำลังมองหาสิ่งที่ต้องการ ArrayList ใน java ฉันคิดว่าไม่เปลี่ยนรูปก็จะใช้ได้เช่นกัน
Andriy Drozdyuk

1
ArrayBufferArrayListการทำงานเช่น Vectorผลงานที่ไม่เปลี่ยนรูป - ArrayListคุณสามารถอ่าน แต่คุณเขียนไม่ได้โดยไม่สร้างใหม่
Rex Kerr

วิธีการเกี่ยวกับรายการย่อย ตัวอย่างเช่นใน java ฉันจะ "data.subList (0, index)"
Andriy Drozdyuk

ไม่เป็นไรฉันเข้าใจแล้ว - เป็น "ชิ้น"! ฉันสามารถแปลง ArrayBuffer เป็น Vector ได้หรือไม่ หรือมีประเภททั่วไปมากขึ้นฉันสามารถกลับจากวิธี? ยกตัวอย่างเช่นใน Java ฉันจะกลับรายการอินเตอร์เฟซ
Andriy Drozdyuk

1
คุณสามารถแปลงArrayBufferเป็นการIndexedSeqใช้.toIndexedSeq; IndexedSeqเป็นประเภททั่วไปมากขึ้น (ในกรณีนี้จริง ๆ แล้วจะนำไปใช้เป็นกVector.) IndexedSeqเป็น supertype ของคอลเลกชันที่เหมาะสมที่จะจัดทำดัชนี นอกจากนี้โปรดทราบว่าคุณสามารถทำได้Vector() ++ myArrayBufferซึ่งจะทำงานได้เกือบทุกคอลเลกชัน (ทั้งสองด้าน) ++สร้างคอลเลกชันใหม่จากทั้งสองที่คุณระบุการรักษาประเภทของทางด้านซ้าย Vector()เป็นเวกเตอร์เปล่าดังนั้นมันจะสร้างสิ่งที่คุณต้องการ
Rex Kerr

121

ปลอดภัยยิ่งขึ้นคือการใช้liftเพื่อให้คุณสามารถแยกค่าหากมีอยู่และล้มเหลวอย่างงดงามหากไม่ได้

data.lift(2)

สิ่งนี้จะส่งคืนไม่มีถ้ารายการไม่ยาวพอที่จะให้องค์ประกอบนั้นและบางส่วน (ค่า) ถ้าเป็น

scala> val l = List("a", "b", "c")
scala> l.lift(1)
Some("b")
scala> l.lift(5)
None

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

คำอธิบาย:

สิ่งนี้ใช้งานได้เนื่องจากรายการapply(ซึ่งเป็นน้ำตาลในวงเล็บคือ e กรัมl(index)) เป็นเหมือนฟังก์ชันบางส่วนที่กำหนดไว้ทุกที่ในรายการมีองค์ประกอบ List.liftวิธีการเปลี่ยนบางส่วนapplyฟังก์ชั่น (ฟังก์ชั่นที่กำหนดไว้เฉพาะสำหรับปัจจัยการผลิตบางส่วน) เป็นฟังก์ชั่นปกติ (ที่กำหนดไว้สำหรับการป้อนข้อมูลใด ๆ ) โดยพื้นห่อผลในตัวเลือก


11
ลิฟท์ที่สวยงาม ฉันสามารถหลีกเลี่ยงข้อผิดพลาด arrayIndexOutOfBound โดยไม่ตรวจสอบขนาดของอาเรย์ ..
Naveen Sachar

9

ทำไมต้องวงเล็บ?

นี่คือคำพูดจากหนังสือการเขียนโปรแกรมในสกาล่า

ความคิดที่สำคัญอีกตัวอย่างจากตัวอย่างนี้จะช่วยให้คุณเข้าใจว่าเหตุใดอาร์เรย์จึงเข้าถึงได้ด้วยวงเล็บใน Scala Scala มีกรณีพิเศษน้อยกว่า Java อาร์เรย์เป็นเพียงตัวอย่างของคลาสเช่นคลาสอื่น ๆ ใน Scala เมื่อคุณใช้วงเล็บล้อมรอบหนึ่งค่าขึ้นไปกับตัวแปร Scala จะแปลงรหัสให้เป็นการเรียกใช้เมธอดที่ชื่อว่า Apply กับตัวแปรนั้น ดังนั้น greetStrings (i) จึงถูกเปลี่ยนเป็น greetStrings.apply (i) ดังนั้นการเข้าถึงองค์ประกอบของอาร์เรย์ใน Scala จึงเป็นการเรียกใช้เมธอดเหมือน ๆ กัน หลักการนี้ไม่ได้ จำกัด อยู่ที่อาร์เรย์: แอปพลิเคชันใด ๆ ของวัตถุไปยังอาร์กิวเมนต์บางตัวในวงเล็บจะถูกแปลงเป็นการเรียกใช้เมธอด ของหลักสูตรนี้จะรวบรวมเฉพาะในกรณีที่ประเภทของวัตถุที่จริงกำหนดวิธีการใช้ ดังนั้นจึงไม่ใช่กรณีพิเศษ เป็นกฎทั่วไป

ต่อไปนี้เป็นตัวอย่างวิธีดึงองค์ประกอบบางอย่าง (องค์ประกอบแรกในกรณีนี้) โดยใช้รูปแบบการเขียนโปรแกรมใช้งาน

  // Create a multdimension Array 
  scala> val a = Array.ofDim[String](2, 3)
  a: Array[Array[String]] = Array(Array(null, null, null), Array(null, null, null))
  scala> a(0) = Array("1","2","3")
  scala> a(1) = Array("4", "5", "6")
  scala> a
  Array[Array[String]] = Array(Array(1, 2, 3), Array(4, 5, 6))

  // 1. paratheses
  scala> a.map(_(0))
  Array[String] = Array(1, 4)
  // 2. apply
  scala> a.map(_.apply(0))
  Array[String] = Array(1, 4)
  // 3. function literal
  scala> a.map(a => a(0))
  Array[String] = Array(1, 4)
  // 4. lift
  scala> a.map(_.lift(0))
  Array[Option[String]] = Array(Some(1), Some(4))
  // 5. head or last 
  scala> a.map(_.head)
  Array[String] = Array(1, 4)


0

นี่เป็นวิธีที่ต้องการในการเข้าถึงข้อมูลของรายการผ่านดัชนีในปัจจุบัน:

scala> val list = List("a","b","c")
scala> list.get(1)
Some("b")
scala> list.get(5)
None

แต่เช่นเดียวกับ Rex Kerr metioned ด้านบน: หากคุณใช้ดัชนีคุณควรพิจารณาใช้ Vector แทนที่จะเป็น List

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