Pavel Fatin Scala Collections Tips and Tricksã®èšäºã®ç¿»èš³ã玹ä»ããŸãã Pavelã¯JetBrainsã§åããŠãããIntelliJ IDEAã®Scalaãã©ã°ã€ã³ãéçºããŠããŸã ã ããã«ãç©èªã¯èè
ã«ä»£ãã£ãŠããŸãã
ãã®èšäºã§ã¯ãScalaã³ã¬ã¯ã·ã§ã³APIã®æ¥åžžçãªäœ¿çšã«å
±éããåçŽåãšæé©åã«ã€ããŠèª¬æããŸã ã
äžéšã®ãã³ãã¯ãã³ã¬ã¯ã·ã§ã³ã©ã€ãã©ãªã®å®è£
ã®è€éãã«åºã¥ããŠããŸãããã»ãšãã©ã®ã¬ã·ãã¯ãå®éã«ã¯èŠèœãšãããã¡ãªã¹ããŒããªå€æã§ãã
ãã®ãªã¹ãã¯ã Scala IntelliJãã©ã°ã€ã³ã®ããã«ã Scala ã³ã¬ã¯ã·ã§ã³ã®å®çšçãªæ€æ»ãéçºããããšããç§ã®è©Šã¿ã«è§ŠçºãããŸããã çŸåšããããã®æ€æ»ãå®è£
ããŠããã®ã§ãIDEAã§Scalaãã©ã°ã€ã³ã䜿çšãããšãéçã³ãŒãåæããèªåçã«æ©æµãåããŸãã
ãã ãããããã®ã¬ã·ãã¯ããèªäœã§äŸ¡å€ããããŸãã ãããã¯ãScalaæšæºã³ã¬ã¯ã·ã§ã³ã©ã€ãã©ãªã®ç解ãæ·±ããã³ãŒããããé«éã§è¡šçŸåè±ãã«ããã®ã«åœ¹ç«ã¡ãŸãã
æŽæ°ïŒ
åéºå¿ããããªãã
é©åãªã€ã³ã¹ãã¯ã·ã§ã³ãéžæããããšã§ã Scalaçšã®IntelliJãã©ã°ã€ã³ã®éçºãæ¯æŽããå®è£
ãè©Šãæ¹æ³ãåŠã¶ããšãã§ããŸãã
å
容ïŒ
1. 2. 3. 4. (Sequences) 4.1. 4.2. 4.3. 4.4. 4.5. 4.6. 4.7. 4.8. 4.9. 4.10. 5. (Sets) 6. Option- 6.1. 6.2. Null 6.3. 6.4. 7. 8.
ãã¹ãŠã®ãµã³ãã«ã³ãŒãã¯GitHubã®ãªããžããªããå
¥æã§ããŸã ã
1.å¡äŸ
ã³ãŒãäŸãããããããããããã«ã次ã®è¡šèšã䜿çšããŸããã
seq
ã¯ã Seq(1, 2, 3)
ãããªSeq(1, 2, 3)
ããŒã¹ã®ã³ã¬ã¯ã·ã§ã³ã®ã€ã³ã¹ã¿ã³ã¹ã§ãset
- Set
ã€ã³ã¹ã¿ã³ã¹ãããšãã°Set(1, 2, 3)
array
- Array(1, 2, 3)
ãªã©ã®Array(1, 2, 3)
option
- Option
ã€ã³ã¹ã¿ã³ã¹ãããšãã°Some(1)
map
- Map
é¡äŒŒããMap
ã€ã³ã¹ã¿ã³ã¹Map(1 -> "foo", 2 -> "bar")
???
-ä»»æã®è¡šçŸp
- T => Boolean
åã®é¢æ°ã®è¿°éšãããšãã°_ > 2
n
ã¯æŽæ°å€ã§ãi
ã¯æŽæ°ã€ã³ããã¯ã¹ã§ãf
ã g
ã¯åçŽãªé¢æ°ã A => B
x
ã y
ããã€ãã®ä»»æã®å€z
åæå€ãŸãã¯ããã©ã«ãå€P
ãã¿ãŒã³
2.æ§æ
ã¬ã·ãã¯å€ç«ããŠããŠèªçµŠèªè¶³ã§ãããšããäºå®ã«ããããããã次ã®ããé«åºŠãªè¡šçŸãžã®æŒžé²çãªå€æã®ããã«èª¿æŽã§ããããšãå¿ããªãã§ãã ããã
seq.filter(_ == x).headOption != None // seq.filter(p).headOption seq.find(p) seq.find(_ == x) != None // option != None option.isDefined seq.find(_ == x).isDefined // seq.find(p).isDefined seq.exists(p) seq.exists(_ == x) // seq.exists(_ == x) seq.contains(x) seq.contains(x)
ãã®ãããã亀æåŠæ¹ã¢ããªã±ãŒã·ã§ã³ã¢ãã«ãïŒ SICPã«é¡äŒŒïŒã«äŸåããããã䜿çšããŠè€éãªè¡šçŸãç°¡çŽ åã§ããŸãã
3.å¯äœçš
ããµã€ãå¹æãã¯ãäž»èŠãªå€æããªã¹ãããåã«èæ
®ãã¹ãåºæ¬çãªæŠå¿µã§ãã
å®éãå¯äœçšãšã¯ãå€ãè¿ãããšã«å ããŠãé¢æ°ãŸãã¯åŒã®å€åŽã§èŠ³å¯ãããã¢ã¯ã·ã§ã³ã®ããšã§ããäŸãã°ïŒ
- å
¥åºåæäœ
- å€æ°ã®å€æŽïŒã¹ã³ãŒãå€ã§å©çšå¯èœïŒ
- ãªããžã§ã¯ãã®ç¶æ
ã®å€åïŒã¹ã³ãŒãå€ã§èŠ³å¯ïŒ
- äŸå€ãã¹ããŒããŸãïŒã¹ã³ãŒãå
ã§ãåŠçãããŸããïŒã
äžèšã®ã¢ã¯ã·ã§ã³ã®ãããããå«ãé¢æ°ãŸãã¯åŒã¯å¯äœçšããããšèšãããããã§ãªããã°ãçŽç²ããšåŒã°ããŸãã
ãªãå¯äœçšãããã»ã©éèŠãªã®ã§ããïŒ åœŒããšå®è¡ã®é åºãéèŠã ããã§ãã ããšãã°ã2ã€ã®ãçŽç²ãªãåŒïŒå¯Ÿå¿ããå€ã«é¢é£ä»ããããŠããŸãïŒïŒ
val x = 1 + 2 val y = 2 + 3
ãããã«ã¯å¯äœçšïŒããªãã¡ãåŒã®å€åŽã§èŠ³å¯ãããå¹æïŒãå«ãŸããŠããªãããããããã®åŒãä»»æã®é åºã§èšç®ã§ããŸã-æåã«x
ã次ã«y
ãŸãã¯æåã«y
ã次ã«x
ããã¯åŸãããçµæã®æ£ç¢ºãã«åœ±é¿ããŸããïŒå¿
èŠã«å¿ããŠãçµæã®å€ããã£ãã·ã¥ããããšãã§ããŸãïŒã 次ã«ã次ã®å€æŽãæ€èšããŸãã
val x = { print("foo"); 1 + 2 } val y = { print("bar"); 2 + 3 }
ããã¯å¥ã®è©±ã§ã-ã¿ãŒããã«ã§ã¯ãfoobarãã®ä»£ããã«ãbarfooããåºåãããããå®è¡é åºãå€æŽããããšã¯ã§ããŸããïŒããã¯æããã«æå³ãããã®ã§ã¯ãããŸããïŒã
ãã®ãããå¯äœçšã®ååšã¯ãã³ãŒãã«é©çšã§ããå€æ ïŒåçŽåãšæé©åã®äž¡æ¹ïŒ ã®æ°ãæžãããŸãã
åæ§ã®èæ
®äºé
ã¯ãé¢é£ããã³ã¬ã¯ã·ã§ã³ãåŒã«ãé©çšãããŸãã ç¯å²å€ã®ã©ããã«ç¹å®ã®builder
ããããšæ³åããŠãã ããïŒ
seq.filter(x => { builder.append(x); x > 3 }).headOption
ååãšããŠã seq.filter(p).headOption
åŒã³åºãã¯seq.filter(p).headOption
ç°¡ç¥åãããŠããŸãããå¯äœçšseq.find(p)
ããããããè¡ãseq.find(p)
ãã
seq.find( x => {builder.append(x); x > 3 })
ãããã®åŒã¯æçµå€ã®ç¹ã§ã¯åçã§ãããå¯äœçšã®ç¹ã§ã¯åçã§ã¯ãããŸããã æåã®åŒã¯ãã¹ãŠã®èŠçŽ ãè¿œå ããæåŸã®åŒã¯è¿°èªã«äžèŽããæåã®å€ãèŠã€ãããšããã«ãã¹ãŠã®èŠçŽ ãç Žæ£ããŸãã ãããã£ãŠããã®ãããªåçŽåã¯ã§ããŸããã
èªåç°¡çŽ åãå¯èœã«ããããã«äœãã§ããŸããïŒ çãã¯ãã³ãŒãå
ã®ãã¹ãŠã®å¯äœçšïŒååãšããŠã³ã¬ã¯ã·ã§ã³ããªããã®ãå«ãïŒã«é¢ããŠåŸãã¹ãé»éåŸã§ãïŒ
- å¯èœãªéãå¯äœçšãé¿ããŠãã ããã
- ãã以å€ã®å Žåãå¯äœçšãã¯ãªãŒã³ãªã³ãŒãããåé¢ããŸãã
ãããã£ãŠã builder
aãïŒå¯äœçšãããAPIãšãšãã«ïŒåãé€ããã builder
aã®åŒã³åºããçŽç²ãªåŒããåé¢ããå¿
èŠããããŸãã ãã®builder
ã¯ãåé€ã§ããªããµãŒãããŒãã£ã®ãªããžã§ã¯ãã§ãããšæ³å®ããŸãããã®ãããåŒã³åºãã®ã¿ãåé¢ã§ããŸãã
seq.foreach(builder.append) seq.filter(_ > 3).headOption
ããã§ãå®å
šã«å€æãå®è¡ã§ããŸãã
seq.foreach(builder.append) seq.find(x > 3)
æž
æœã§çŸããïŒ å¯äœçšã®åé¢ã«ãããèªåå€æãå¯èœã«ãªããŸããã è¿œå ã®å©ç¹ã¯ãæ確ãªåé¢ãååšãããããçµæã®ã³ãŒãã人ãç解ãããããªãããšã§ãã
å¯äœçšãåé¢ããããšã®æãæçœã§ãåæã«æãéèŠãªå©ç¹ã¯ãä»ã®å¯èœãªæé©åã«é¢ä¿ãªããã³ãŒãã®ä¿¡é Œæ§ãåäžãããããšã§ãã äŸã«ã€ããŠïŒåæåŒã¯ã Seq
çŸåšã®å®è£
ã«å¿ããŠãããŸããŸãªå¯äœçšãåŒãèµ·ããå¯èœæ§ããããŸãã ããšãã°ã Vector
å Žåããã¹ãŠã®èŠçŽ ãè¿œå ããã Stream
å Žåãè¿°èªãšã®æåã®äžèŽãæåããåŸããã¹ãŠã®èŠçŽ ãã¹ããããããŸãïŒã¹ããªãŒã ã¯ãé
延ãã§ãããããèŠçŽ ã¯å¿
èŠãªå Žåã«ã®ã¿èšç®ãããŸãïŒã å¯äœçšã®åé¢ã«ããããããã®äžç¢ºå®æ§ãåé¿ã§ããŸãã
4.ã·ãŒã±ã³ã¹
ãã®ã»ã¯ã·ã§ã³ã®ã¢ããã€ã¹ã¯Seq
çžç¶äººã«é©çšãããŸãããäžéšã®å€æã¯ä»ã®ã¿ã€ãã®ã³ã¬ã¯ã·ã§ã³ïŒã³ã¬ã¯ã·ã§ã³ã§ã¯ãªãïŒã«æå¹ã§ããããšãã°ã Set
ã Option
ã Map
ããã«ã¯Iterator
ïŒãããã¯ãã¹ãŠã¢ããã¡ãœãããšåæ§ã®ã€ã³ã¿ãŒãã§ãŒã¹ãæäŸããããïŒ
4.1äœæ
空ã®ã³ã¬ã¯ã·ã§ã³ãæ瀺çã«äœæãã
// Seq[T]() // Seq.empty[T]
äžéšã®äžå€ã®ã³ã¬ã¯ã·ã§ã³ã¯ã©ã¹ã«ã¯ã empty
ã¡ãœããã®ã·ã³ã°ã«ãã³å®è£
ãããempty
ã ãã ãããã¹ãŠã®ãã¡ã¯ããªã¡ãœãããäœæãããã³ã¬ã¯ã·ã§ã³ã®é·ãããã§ãã¯ããããã§ã¯ãããŸããã ãã®ãããã³ã³ãã€ã«æ®µéã§voidãæå®ããããšã«ãããããŒãäžã®ã¹ããŒã¹ïŒã€ã³ã¹ã¿ã³ã¹ã®åå©çšã«ããïŒãŸãã¯ããã»ããµãŒãµã€ã¯ã«ïŒå®è¡æã®æ¬¡å
ãã§ãã¯ã«è²»ããããšãã§ããïŒãç¯çŽã§ããŸãã
以äžã«ãé©çšå¯èœïŒ Set
ã Option
ã Map
ã Iterator
ã
4.2é·ã
é
åã®å Žåã size
代ããã«length
ã䜿çšãsize
// array.size // array.length
size
ãšlength
ã¯æ¬è³ªçã«å矩ã§ãããScala 2.11ã§ã¯Array.size
åŒã³åºãã¯æé»ã®å€æã«ãã£ãŠè¡ãããåã¡ãœããåŒã³åºãã®äžéã©ãããŒãªããžã§ã¯ããäœæããŸãã ãã¡ãããJVMã®ãšã¹ã±ãŒãåæãæå¹ã«ããªãéããäžæãªããžã§ã¯ãã¯ã¬ããŒãžã³ã¬ã¯ã¿ãŒã®è² æ
ã«ãªããã³ãŒãã®ããã©ãŒãã³ã¹ãäœäžãããŸãïŒç¹ã«ã«ãŒãå
ïŒã
isEmptyãæåŠããªãã§ãã ãã
// !seq.isEmpty !seq.nonEmpty // seq.nonEmpty seq.isEmpty
åçŽãªããããã£ã¯ãè€ååŒãããèŠèŠçãªãã€ãºãå°ãªãã§ãã
以äžã«ãé©çšå¯èœïŒ Set
ã Option
ã Map
ã Iterator
ã
voidããã§ãã¯ãããšãã«é·ããèšç®ããªãã§ãã ããã
äžæ¹ã§ã¯ãåçŽãªããããã£ã¯è€ååŒãããã¯ããã«ç°¡åã«èªèãããŸãã äžæ¹ã LinearSeq
çžç¶äººïŒ List
ãªã©ïŒã¯ããªã¹ãã®é·ããèšç®ããããã«ïŒ IndexedSeq
O(1)
代ããã«O(n)
æéãå¿
èŠãšããå Žåããããããäžè¬çã«ãé·ãã®èšç®ãé¿ããããšã§ã³ãŒããé«éåã§ããŸãããã®å€ã¯ããŸãå¿
èŠãããŸããã
ç¡éã¹ããªãŒã ã®.length
åŒã³åºãã¯æ±ºããŠçµäºããªãå¯èœæ§ããããããåžžã«æ瀺çã«ã¹ããªãŒã ã®ç©ºæ§ã確èªããŠãã ããã
é©çšå¯Ÿè±¡ïŒ Set
ã Map
ã
æ¯èŒäžã«ã³ã¬ã¯ã·ã§ã³ã®ãã«ãµã€ãºãèšç®ããªãã§ãã ããã
// seq.length > n seq.length < n seq.length == n seq.length != n // seq.lengthCompare(n) > 0 seq.lengthCompare(n) < 0 seq.lengthCompare(n) == 0 seq.lengthCompare(n) != 0
ã³ã¬ã¯ã·ã§ã³ã®ãµã€ãºã®èšç®ã¯ãäžéšã®ã¿ã€ãã®ã³ã¬ã¯ã·ã§ã³ã§ã¯éåžžã«ãé«äŸ¡ãªãèšç®ã«ãªãå¯èœæ§ãããããã LinearSeq
ïŒ Seq
å€ã§é衚瀺ã«ã§ããO(length min n)
ã®æ¯èŒæéãO(length)
ããO(length min n)
ã«LinearSeq
ã§ããŸãã ããã«ãç¡éã®ã¹ããªãŒã ãåŠçããå Žåããã®ã¢ãããŒãã¯äžå¯æ¬ ã§ãã
emptyããã§ãã¯ããããã«exists
ã䜿çšããªãã§ãã ããã
// seq.exists(_ => true) seq.exists(const(true)) // seq.nonEmpty
ãã¡ããããã®ãããªããªãã¯ã¯å®å
šã«åé·ã§ãã
é©çšå¯Ÿè±¡ïŒã»ããããªãã·ã§ã³ãããããã€ãã¬ãŒã¿ãŒã
4.3å¹³ç
é
åã®å
容ãæ¯èŒããããã«==
ã«äŸåããªãã§ãã ãã
ç䟡æ§ãã¹ãã¯ãé
åã®ããŸããŸãªã€ã³ã¹ã¿ã³ã¹ã«å¯ŸããŠåžžã«false
ãè¿ããŸãã
該åœãããã®ïŒ Iterator
ç°ãªãã«ããŽãªã®ã³ã¬ã¯ã·ã§ã³ã®åçæ§ããã¹ãããªãã§ãã ãã
// seq == set // seq.toSet == set
ç䟡æ§ãã§ãã¯ã䜿çšããŠãã³ã¬ã¯ã·ã§ã³ãšç°ãªãã«ããŽãªïŒäŸïŒ List
ãšSet
ïŒãæ¯èŒã§ããŸãã
ãã®ãã§ãã¯ã®æå³ã«ã€ããŠåèããŠãã ããïŒäžèšã®äŸ-ã·ãŒã±ã³ã¹å
ã®éè€ãã©ã®ããã«èæ
®ãããïŒã
sameElements
ã䜿çšããŠéåžžã®ã³ã¬ã¯ã·ã§ã³ãæ¯èŒããªãã§ãã ãã
åçæ§ãã¹ãã¯ãåãã«ããŽãªã®ã³ã¬ã¯ã·ã§ã³ãæ¯èŒããæ¹æ³ã§ãã çè«çã«ã¯ãããã«ãããæœåšçãªã€ã³ã¹ã¿ã³ã¹ãã§ãã¯ãåå ã§ããã©ãŒãã³ã¹ãåäžããããšããããŸãïŒ eq
ãéåžžã¯ã¯ããã«é«éïŒã
æ瀺çã«å¯Ÿå¿ã䜿çšããªãã§ãã ãã
åãããšãè¡ãçµã¿èŸŒã¿ã¡ãœãããæ¢ã«ãããŸãã äž¡æ¹ã®åŒã§ã¯ãèŠçŽ ã®é åºãèæ
®ãããŸãã ç¹°ãè¿ãã«ãªããŸãããçç£æ§ã®åäžã®æ©æµãåããããšãã§ããŸãã
4.4玢åŒä»ã
ã€ã³ããã¯ã¹ã§æåã®ã¢ã€ãã ãååŸããªãã§ãã ãã
// seq(0) // seq.head
äžéšã®ã³ã¬ã¯ã·ã§ã³ã¯ã©ã¹ã§ã¯ãæŽæ°ãããã¢ãããŒããå°ãéããªãå ŽåããããŸãïŒããšãã°ã List.apply
ã³ãŒãã確èªããŠãã ããïŒã ããã«ãããããã£ãžã®ã¢ã¯ã»ã¹ã¯ãåŒæ°ã䜿çšããŠã¡ãœãããåŒã³åºããããã¯ããã«ç°¡åã§ãïŒæ§æçã«ãæå³çã«ãïŒã
ã€ã³ããã¯ã¹ã§æåŸã®ã¢ã€ãã ãååŸããªãã§ãã ãã
// seq(seq.length - 1) // seq.last
æåŸã®åŒã¯ããæ確ã§ãã³ã¬ã¯ã·ã§ã³ã®é·ãã®äžå¿
èŠãªèšç®ãé¿ããŸãïŒãããŠç·åœ¢ã·ãŒã±ã³ã¹ã®å Žåãããã«ã¯å€ãã®æéãããããŸãïŒã ããã«ãäžéšã®ã³ã¬ã¯ã·ã§ã³ã¯ã©ã¹ã¯ãã€ã³ããã¯ã¹ã¢ã¯ã»ã¹ãããå¹ççã«æåŸã®ã¢ã€ãã ãååŸã§ããŸãã
ã³ã¬ã¯ã·ã§ã³å
ã®ã€ã³ããã¯ã¹ãæ瀺çã«ãã§ãã¯ããªãã§ãã ãã
// if (i < seq.length) Some(seq(i)) else None // seq.lift(i)
æå³çã«ã¯ã2çªç®ã®åŒã¯åçã§ãããããè¡šçŸçã«ã¯
headOptionããšãã¥ã¬ãŒãããªãã§ãã ãã
// if (seq.nonEmpty) Some(seq.head) else None seq.lift(0) // seq.headOption
ç°¡ç¥åãããåŒã¯ããç°¡æœã§ãã
lastOption
ãšãã¥ã¬ãŒãããªã
// if (seq.nonEmpty) Some(seq.last) else None seq.lift(seq.length - 1) // seq.lastOption
æåŸã®åŒã¯çããªã£ãŠããŸãïŒãããŠæœåšçã«é«éã§ãïŒã
indexOf
ããã³lastIndexOf
åŒæ°ã¿ã€ãã«æ³šæããŠãã ãã
// Seq(1, 2, 3).indexOf("1") // Seq(1, 2, 3).lastIndexOf("2") // // Seq(1, 2, 3).indexOf(1) Seq(1, 2, 3).lastIndexOf(2)
åæ£ã®indexOf
ã«ããã indexOf
ã¡ãœãããšlastIndexOf
ã¡ãœããã¯Any
åã®åŒæ°ãåãå
¥ããŸãã å®éã«ã¯ãããã«ãããã³ã³ãã€ã«æ®µéã§æ€åºã§ããªããã°ãèŠã€ãã«ãããªããŸãã IDEã®ãµããŒãæ€æ»ãè¡ãããå Žæã§ãã
ã·ãŒã±ã³ã¹ã€ã³ããã¯ã¹ã®ç¯å²ãæåã§äœæããªãã§ãã ãã
ã·ãŒã±ã³ã¹å
ã®ãã¹ãŠã®ã€ã³ããã¯ã¹ã®ç¯å²ãè¿ãçµã¿èŸŒã¿ã¡ãœããããããŸãã
ã³ã¬ã¯ã·ã§ã³ãã€ã³ããã¯ã¹ã«æåã§é¢é£ä»ããããã«zipã䜿çšããªãã§ãã ãã
ãŸããæåŸã®åŒãçããªããŸãã ããã«ãã³ã¬ã¯ã·ã§ã³ã®ãµã€ãºã®é ãããèšç®ïŒç·åœ¢ã·ãŒã±ã³ã¹ã®å Žåã¯é«äŸ¡ã«ãªãå¯èœæ§ãããïŒãé¿ããããšã«ãããããã©ãŒãã³ã¹ã®åäžãæåŸ
ã§ããŸãã
åŸè
ã®åŒã®è¿œå ã®å©ç¹ã¯ãç¡éã®ã³ã¬ã¯ã·ã§ã³ïŒäŸïŒ Stream
ïŒã§ããŸãæ©èœããããšã§ãã
IndexedSeqã€ã³ã¹ã¿ã³ã¹ãé¢æ°ãªããžã§ã¯ããšããŠäœ¿çšããŸãã
// (seq: IndexedSeq[T]) Seq(1, 2, 3).map(seq(_)) // Seq(1, 2, 3).map(seq)
IndexedSeq[T]
ã€ã³ã¹ã¿ã³ã¹ã¯Function1[Int, T]
ã§ãããããããã®ãŸãŸäœ¿çšã§ããŸãã
4.5ååš
æ¯èŒè¿°èªã䜿çšããŠèŠçŽ ããã§ãã¯ããªãã§ãã ãã
2çªç®ã®åŒã¯æå³çã«åçã§ãããããè¡šçŸåè±ãã§ãã ãããã®åŒãSet
ã«é©çšããããšãã»ããæ€çŽ¢ã¯O(1)
ãªãåŸåããããããããã©ãŒãã³ã¹ãåçã«ç°ãªãå¯èœæ§ããããŸãO(1)
exists
å Žåexists
å
éšã€ã³ããã¯ã¹ã䜿çšãããªãããïŒã
以äžã«ãé©çšå¯èœïŒ Set
ã Option
ã Iterator
ã
contains
ããåŒæ°ã®ã¿ã€ãã«æ³šæããŠãã ãã
// Seq(1, 2, 3).contains("1") // // Seq(1, 2, 3).contains(1)
indexOf
ãlastIndexOf
ããã«ãã¿ã€ãAny
åŒæ°ãåãã¡ãœãããcontains
ãŸããããã«ãããã³ã³ãã€ã«æ®µéã§ã¯æ€åºãããªããã°ãèŠã€ãã«ãããªããŸãã ãããã«æ³šæããŠãã ããã
äžçåŒè¿°éšã䜿çšããŠãæ¬ èœããŠããèŠçŽ ããã§ãã¯ããªãã§ãã ãã
// seq.forall(_ != x) // !seq.contains(x)
ç¹°ãè¿ããŸãããæåŸã®åŒã¯ããã¯ãªãŒã³ã§ãããããããé«éã§ãïŒç¹ã«ã»ããã®å ŽåïŒã
以äžã«ãé©çšå¯èœïŒ Set
ã Option
ã Iterator
ã
çºçãã«ãŠã³ãããŠååšã確èªããªã
// seq.count(p) > 0 seq.count(p) != 0 seq.count(p) == 0 // seq.exists(p) seq.exists(p) !seq.exists(p)
æããã«ãæ¡ä»¶ã«äžèŽããã¢ã€ãã ãã³ã¬ã¯ã·ã§ã³å
ã«ãããã©ãããç¥ãå¿
èŠãããå ŽåãäžèŽããã¢ã€ãã ã®æ°ãã«ãŠã³ãããããšã¯åé·ã§ãã ç°¡ç¥åãããåŒã¯ãããã¯ãªãŒã³ã§é«éã«èŠããŸãã
- è¿°èª
p
ã¯çŽé¢æ°ã§ãªããã°ãªããŸããã - 該åœãããã®ïŒ
Set
ã Map
ã Iterator
ã
ååšã確èªããããã«ãã£ã«ã¿ãªã³ã°ã«é Œããªãã§ãã ãã
// seq.filter(p).nonEmpty seq.filter(p).isEmpty // seq.exists(p) !seq.exists(p)
filter
åŒã³åºãã¯ãããŒãã®ã¹ããŒã¹ãå æããŠGCãããŒãããäžéã³ã¬ã¯ã·ã§ã³ãäœæããŸãã ããã«ãåè¿°ã®åŒã¯ãã¹ãŠã®ãªã«ã¬ã³ã¹ãæ€åºããŸãããæåã®åŒã®ã¿ãæ€åºããå¿
èŠããããŸãïŒã³ã¬ã¯ã·ã§ã³ã®å¯èœãªå
容ã«ãã£ãŠã¯ã³ãŒããé
ããªãå¯èœæ§ããããŸãïŒã é
延ã³ã¬ã¯ã·ã§ã³ïŒ Stream
ããç¹ã«Iterator
ïŒã®å Žåãæœåšçãªããã©ãŒãã³ã¹ã®åäžã¯ããã»ã©éèŠã§ã¯ãããŸããã
- è¿°èª
p
ã¯çŽé¢æ°ã§ãªããã°ãªããŸããã - 以äžã«ãé©çšå¯èœïŒ
Set
ã Option
ã Map
ã Iterator
ã
ååšã確èªããããã«æ€çŽ¢ã«é Œããªãã§ãã ãã
// seq.find(p).isDefined seq.find(p).isEmpty // seq.exists(p) !seq.exists(p)
æ€çŽ¢ã¯ãã£ã«ã¿ãªã³ã°ãããééããªãåªããŠããŸãããããã¯å¶éããã¯ã»ã©é ãã§ãïŒå°ãªããšãæ確ãã®ç¹ã§ã¯ïŒã
以äžã«ãé©çšå¯èœïŒ Set
ã Option
ã Map
ã Iterator
ã
4.6ãã£ã«ã¿ãªã³ã°
ãã£ã«ã¿ãŒè¿°èªãæåŠããªãã§ãã ãã
æåŸã®åŒã¯æ§æçã«åçŽã§ãïŒæå³çã«åçã§ãããšããäºå®ã«ããããããïŒã
以äžã«ãé©çšå¯èœïŒ Set
ã Option
ã Map
ã Iterator
ã
ã«ãŠã³ãããããã«ãã£ã«ã¿ãªã³ã°ããªãã§ãã ãã
// seq.filter(p).length // seq.count(p)
filter
åŒã³åºãã¯ãäžéã®ïŒããŸãå¿
èŠã§ã¯ãªãïŒã³ã¬ã¯ã·ã§ã³ãäœæããŸããããã¯ãããŒãã®ã¹ããŒã¹ãå æããGCãããŒãããŸãã
以äžã«ãé©çšå¯èœïŒ Set
ã Option
ã Map
ã Iterator
ã
æåã®åºçŸãèŠã€ããããã«ãã£ã«ã¿ãªã³ã°ã䜿çšããªãã§ãã ãã
ãã¡ããã seq
é
延ã³ã¬ã¯ã·ã§ã³ïŒ Stream
ãªã©ïŒã§ãªãå Žåãæåã®èŠçŽ ã®ã¿ãå¿
èŠã§ãããšããäºå®ã«ããããããããã£ã«ã¿ãªã³ã°ã¯ãã¹ãŠã®çºçãæ€åºïŒããã³äžæã³ã¬ã¯ã·ã§ã³ãäœæïŒããŸãã
以äžã«ãé©çšå¯èœïŒ Set
ã Option
ã Map
ã Iterator
ã
4.7䞊ã¹æ¿ã
ããããã£ã§æåã§äžŠã¹æ¿ããªãã§ãã ãã
// seq.sortWith(_.property < _.property) // seq.sortBy(_.property)
ãããè¡ãã«ã¯ãããæ確ã§è¡šçŸåè±ããªç¬èªã®æ¹æ³ããããŸãã
IDã§æåã§äžŠã¹æ¿ããªãã§ãã ãã
ãããŠããã®ããã®æ¹æ³ããããŸãã
ã¯ã³ã¹ãããã§éãœãŒã
// seq.sorted.reverse seq.sortBy(_.property).reverse seq.sortWith(f(_, _)).reverse // seq.sorted(Ordering[T].reverse) seq.sortBy(_.property)(Ordering[T].reverse) seq.sortWith(!f(_, _))
ãããã£ãŠãäžéã³ã¬ã¯ã·ã§ã³ã®äœæãåé¿ããè¿œå ã®å€æãæé€ã§ããŸãïŒããŒãã¹ããŒã¹ãšããã»ããµãµã€ã¯ã«ãç¯çŽããããïŒã
ãœãŒãã䜿çšããŠæå°èŠçŽ ãèŠã€ããªãã§ãã ãã
// seq.sorted.head seq.sortBy(_.property).head // seq.min seq.minBy(_.property)
åŸè
ã®ã¢ãããŒãã¯ããè¡šçŸåè±ãã§ãã ããã«ãè¿œå ã®ã³ã¬ã¯ã·ã§ã³ãäœæãããªããšããäºå®ã«ãããããé«éã«åäœããŸãã
æ倧ã®èŠçŽ ãèŠã€ããããã«ãœãŒãã䜿çšããªãã§ãã ãã
// seq.sorted.last seq.sortBy(_.property).last // seq.max seq.maxBy(_.property)
説æã¯åã®ãã³ããšåãã§ãã
4.8ç³ã¿èŸŒã¿
éé¡ãæåã§èšç®ããªãã§ãã ãã
ãã®ã¢ãããŒãã®å©ç¹ã¯ãæå¿«ããšè¡šçŸåã§ãã
- ãã®ä»ã®å¯èœãªæ¹æ³ïŒ
reduceLeft
ã reduceRight
ã foldLeft
ã foldRight
ã z
ã0
çããå Žåã2çªç®ã®å€æã¯æåã®å€æã«çœ®ãæããããšãã§ããŸãã- 該åœãããã®ïŒ
Set
ã Iterator
ã
äœæ¥ãæåã§èšç®ããªãã§ãã ãã
çç±ã¯ãåã®ã±ãŒã¹ãšåãã§ãã
z
ã1
å Žåã2çªç®ã®å€æã¯æåã®å€æã«çœ®ãæããããšãã§ããŸãã- 該åœãããã®ïŒ
Set
ã Iterator
ã
æå°ã¢ã€ãã ãæåã§æ€çŽ¢ããªãã§ãã ãã
// seq.reduce(_ min _) seq.fold(z)(_ min _) // seq.min z min seq.min
çè«çæ ¹æ ã¯åã®ã±ãŒã¹ãšåãã§ãã
該åœãããã®ïŒ Set
ã Iterator
ã
æ倧ã¢ã€ãã ãæåã§æ€çŽ¢ããªãã§ãã ãã
// seq.reduce(_ max _) seq.fold(z)(_ max _) // seq.max z max seq.max
ãã¹ãŠåã®ã±ãŒã¹ãšåãã§ãã
該åœãããã®ïŒ Set
ã Iterator
ã
forall
ãšãã¥ã¬ãŒãããªã
// seq.foldLeft(true)((x, y) => x && p(y)) !seq.map(p).contains(false) // seq.forall(p)
ç°¡çŽ åã®ç®æšã¯ãæå¿«ããšè¡šçŸåã§ãã
- è¿°èª
p
ã¯çŽé¢æ°ã§ãªããã°ãªããŸããã - 以äžã«ãé©çšå¯èœïŒ
Set
ã Option
ïŒ2è¡ç®ïŒã Iterator
ã
ãšãã¥ã¬ãŒãããªã
// seq.foldLeft(false)((x, y) => x || p(y)) seq.map(p).contains(true) // seq.exists(p)
ãã¹ãŠã®æå¿«ããšè¡šçŸåã§ãæåŸã®åŒã¯ããé«éã«åäœãïŒæåã®é©åãªèŠçŽ ãèŠã€ãããšããã«åŸç¶ã®èŠçŽ ã®åŠçãåæ¢ããŸãïŒãç¡éã®ã·ãŒã±ã³ã¹ã§æ©èœããŸãã
- è¿°èª
p
ã¯çŽé¢æ°ã§ãªããã°ãªããŸããã - 以äžã«ãé©çšå¯èœïŒ
Set
ã Option
ïŒ2è¡ç®ïŒã Iterator
ã
map
ãšãã¥ã¬ãŒãããŸãã
// seq.foldLeft(Seq.empty)((acc, x) => acc :+ f(x)) seq.foldRight(Seq.empty)((x, acc) => f(x) +: acc) // seq.map(f)
ããã¯ãç³ã¿èŸŒã¿ã«ãããããïŒãããïŒã®é¢æ°åããã°ã©ãã³ã°å®è£
ã®ãã¯ã©ã·ãã¯ãã§ãã ééããªãæçã§ãããã䜿çšããå¿
èŠã¯ãªãã ãããè¡ãã«ã¯ãçµã¿èŸŒã¿ã®è¡šçŸåè±ããªã¡ãœããã䜿çšããŸãïŒããã¯ãå®è£
ã§åçŽãªwhile
䜿çšãããããé«éã§ãïŒã
以äžã«ãé©çšå¯èœïŒ Set
ã Option
ã Iterator
ã
filter
ãšãã¥ã¬ãŒãããªã
// seq.foldLeft(Seq.empty)((acc, x) => if (p(x)) acc :+ x else acc) seq.foldRight(Seq.empty)((x, acc) => if (p(x)) x +: acc else acc) // seq.filter(p)
çç±ã¯ãåã®ã±ãŒã¹ãšåãã§ãã
以äžã«ãé©çšå¯èœïŒ Set
ã Option
ã Iterator
ã
reverse
ãšãã¥ã¬ãŒãããªã
// seq.foldLeft(Seq.empty)((acc, x) => x +: acc) seq.foldRight(Seq.empty)((x, acc) => acc :+ x) // seq.reverse
ç¹°ãè¿ãã«ãªããŸãããçµã¿èŸŒã¿ã®ã¡ãœããã¯ããé«éã§ã¯ãªãŒã³ã§ãã
以äžã«ãé©çšå¯èœïŒ Set
ã Option
ã Iterator
ã
4.9æ¯èŒ
Scalaã§ã®ãã¿ãŒã³ãããã³ã°ãšéšåé¢æ°ã®ã¹ã¿ã³ãã¢ãã³ã®ãã³ãã次ã«ç€ºããŸã ã
ãã¿ãŒã³ãããã³ã°ãæã€é¢æ°ã®ä»£ããã«éšåé¢æ°ã䜿çšãã
// seq.map { _ match { case P => ??? // x N } } // seq.map { case P => ??? // x N }
æŽæ°ãããåŒã¯åæ§ã®çµæãäžããããã·ã³ãã«ã«èŠããŸãã
äžèšã®å€æã¯ã map
é¢æ°ã®åŒæ°ã ãã§ãªããä»»æã®é¢æ°ã«é©çšã§ããŸãã ãã®ãã³ãã¯ã³ã¬ã¯ã·ã§ã³ã«éå®ãããŸããã ãã ããScalaã³ã¬ã¯ã·ã§ã³ã©ã€ãã©ãªAPIã®é«éé¢æ°ã®æ®éæ§ãèæ
®ãããšããã®é¢æ°ã¯äŸ¿å©ã§ãã
flatMap
collect
// seq.flatMap { case P => Seq(???) // x N case _ => Seq.empty } // seq.collect { case P => ??? // x N }
.
: Set
, Option
, Map
, Iterator
.
match
collect
,
// v match { case P => Seq(???) // x N case _ => Seq.empty } // Seq(v) collect { case P => ??? // x N }
, case- , , match
collect
. , case
.
Option
, .
: Set
, Option
, Iterator
.
collectFirst
// seq.collect{case P => ???}.headOption // seq.collectFirst{case P => ???}
, .
- .
- :
Set
, Map
, Iterator
.
4.10
filter
// seq.filter(p1).filter(p2) // seq.filter(x => p1(x) && p2(x))
( filter
), .
, ( ), : seq.view.filter(p1).filter(p2).force
.
p1
p2
.- :
Set
, Option
, Map
, Iterator
.
map
// seq.map(f).map(g) // seq.map(f.andThen(g))
, .
, view ( ), : seq.view.map(f).map(g).force
.
f
g
.- :
Set
, Option
, Map
, Iterator
.
// seq.sorted.filter(p) // seq.filter(p).sorted
â . , .
map
() , ( List
). , , , .
.
Set
( ), .
slice
// seq.drop(x).take(y) // seq.slice(x, x + y)
, . , .
: Set
, Map
, Iterator
.
splitAt
( List
, Stream
), - , .
: Set
, Map
.
span
, .
p
.- :
Set
, Map
, Iterator
.
partition
// val seq1 = seq.filter(p) val seq2 = seq.filterNot(p) // val (seq1, seq2) = seq.partition(p)
-,
p
.- :
Set
, Map
, Iterator
.
takeRight
// seq.reverse.take(n).reverse // seq.takeRight(n)
( , ).
flatten
// (seq: Seq[Seq[T]]) seq.reduce(_ ++ _) seq.fold(Seq.empty)(_ ++ _) seq.flatMap(identity) // seq.flatten
: .
: Set
, Option
, Iterator
.
flatMap
// (f: A => Seq[B]) seq.map(f).flatten // seq.flatMap(f)
- . , .
: Set
, Option
, Iterator
.
map
// seq.map(???) // // seq.foreach(???)
, map
. , .
: Set
, Option
, Map
, Iterator
.
unzip
// (seq: Seq[(A, B]]) seq.unzip._1 // seq.map(_._1)
, - .
- :
unzip3
. - :
Set
, Option
, Map
, Iterator
.
( ).
1) .
// seq.map(f).flatMap(g).filter(p).reduce(???) // seq.view.map(f).flatMap(g).filter(p).reduce(???)
reduce
, , : reduceLeft
, reduceRight
, fold
, foldLeft
, foldRight
, sum
, product
, min
, max
, head
, headOption
, last
, lastOption
, indexOf
, lastIndexOf
, find
, contains
, exists
, count
, length
, mkString
, ..
â , , - , GC. , ( map
, flatMap
, filter
, ++,
..) «» ( Stream
) , , .
(view) â , , :
, view
.
2) , .
, - â force
( ):
// seq.map(f).flatMap(g).filter(p) // seq.view.map(f).flatMap(g).filter(p).force
â , , , withFilter
:
seq.withFilter(p).map(f)
"for comprehensions". , â , (, ). , ( ) ( veiw
force
)
, withFilter
- .
3) .
// seq.map(f).flatMap(g).filter(p).toList // seq.view.map(f).flatMap(g).filter(p).toList
force
-, .
« + ». breakOut
:
seq.map(f)(collection.breakOut): List[T]
, :
- (, , ),
- (, ,
map
, flatMap
, filter
, fold
, ..), - ( , Scala).
, , breakOut
.
.
- (
f
g
) ( p
) ( , , ). - :
Set
, Map
.
Scala « », « » (âassignment operatorsâ) â x <op>= y
x = x <op> y
, : <op>
(: +
, -
, .). , <op>
:
, - (.. , ). :
// list = x :: list list1 = list2 ::: list1 stream = x
.
Set
, Map
, Iterator
( ).
// seq.foldLeft(Set.empty)(_ + _) seq.foldRight(List.empty)(_ :: _) // seq.toSet seq.toList
, , . , , .
: Set
, Option
, Iterator
.
toSeq
.
- , Seq(...)
( , Vector ), toSeq
( Stream
, Iterator
view
) . TraversableOnce.toSeq
Stream
, , . , , .
:
val source = Source.fromFile("lines.txt") val lines = source.getLines.toSeq source.close() lines.foreach(println)
IOException
, , .
, toStream
, , toVector
toSeq
.
// (seq: Seq[String]) seq.reduce(_ + _) seq.reduce(_ + separator + _) seq.fold(prefix)(_ + _) seq.map(_.toString).reduce(_ + _) // seq: Seq[T] seq.foldLeft(new StringBuilder())(_ append _) // seq.mkString seq.mkString(prefix, separator, "")
, StringBuilder
.
- :
reduceLeft
, reduceRight
, foldLeft
, foldRight
. - :
Set
, Option
, Iterator
.
5. (Sets)
. , .
sameElements
( ), .
sameElements
, , .
, : , LinkedHashSet
.
: Map
.
Set -
// (set: Set[Int]) Seq(1, 2, 3).filter(set(_)) Seq(1, 2, 3).filter(set.contains) // Seq(1, 2, 3).filter(set)
Set[T]
Function1[T, Boolean]
, .
// set1.filter(set2.contains) set1.filter(set2) // set1.intersect(set2) // set1 & set2
, .
, , .
// set1.filterNot(set2.contains) set1.filterNot(set2) // set1.diff(set2) // set1 &~ set2
, , .
, , .
6. Options
Option
Scala , ( ..) , , - .
Option. , , Option
API.
6.1
Option None
// option == None option != None // option.isEmpty option.isDefined
, , , Option
.
, Option[T]
T
, scalac ( ), .
Option
Some
// option == Some(v) option != Some(v) // option.contains(v) !option.contains(v)
.
isInstanceOf
// option.isInstanceOf[Some[_]] // option.isDefined
.
// option match { case Some(_) => true case None => false } option match { case Some(_) => false case None => true } // option.isDefined option.isEmpty
, â . , .
: Seq
, Set
.
,
// !option.isEmpty !option.isDefined !option.nonEmpty // seq.isDefined seq.isEmpty seq.isEmpty
, â , .
, : isDefined
( option) nonEmpty
( ). , Option
.
6.2 Null
null
, Option
// if (v != null) Some(v) else None // Option(v)
.
null
// option.getOrElse(null) // option.orNull
, .
6.3
, , Option
.
, Option
, , « Option
â map
, flatMap
, filter
foreach
». , "check & get" ( ) , if
.
â , «» :
- ,
NoSuchElementException
MatchError
.
getOrElse
// if (option.isDefined) option.get else z option match { case Some(it) => it case None => z } // option.getOrElse(z)
orElse
// if (option1.isDefined) option1 else option2 option1 match { case Some(it) => Some(it) case None => option2 } // option1.orElse(option2)
exists
// option.isDefined && p(option.get) if (option.isDefined) p(option.get) else false option match { case Some(it) => p(it) case None => false } // option.exists(p)
forall
// option.isEmpty || (option.isDefined && p(option.get)) if (option.isDefined) p(option.get) else true option match { case Some(it) => p(it) case None => true } // option.forall(p)
contains
// option.isDefined && option.get == x if (option.isDefined) option.get == x else false option match { case Some(it) => it == x case None => false } // option.contains(x)
foreach
// if (option.isDefined) f(option.get) option match { case Some(it) => f(it) case None => } // option.foreach(f)
filter
// if (option.isDefined && p(option.get)) option else None option match { case Some(it) && p(it) => Some(it) case _ => None } // option.filter(p)
map
// if (option.isDefined) Some(f(option.get)) else None option match { case Some(it) => Some(f(it)) case None => None } // option.map(f)
flatMap
// (f: A => Option[B]) if (option.isDefined) f(option.get) else None option match { case Some(it) => f(it) case None => None } // option.flatMap(f)
6.4
map
getOrElse
fold
// option.map(f).getOrElse(z) // option.fold(z)(f)
( z
â ), . (- Scala), .
, - , , .
exists
// option.map(p).getOrElse(false) // option.exists(p)
( Option
). getOrElse
.
flatten
// (option: Option[Option[T]]) option.map(_.get) option.getOrElse(None) // option.flatten
.
Option
Seq
// option.map(Seq(_)).getOrElse(Seq.empty) option.getOrElse(Seq.empty) // option: Option[Seq[T]] // option.toSeq
, .
7.
, , .
// map.find(_._1 == k).map(_._2) // map.get(k)
, , - , Map
(, ) â . , .
get
,
// Before map.get(k).get // After map(k)
Option
, (raw) .
lift
get
// Before map.lift(k) // After map.get(k)
, ( ), . lift
, ( Map
PartialFunction
) .
get
getOrElse
// map.get(k).getOrElse(z) // map.getOrElse(k, z)
, . z
, .
Map -
// (map: Map[Int, T]) Seq(1, 2, 3).map(map(_)) // Seq(1, 2, 3).map(map)
Map[K, V] Function1[K, V], .
// map.map(_._1) map.map(_._1).toSet map.map(_._1).toIterator // map.keys map.keySet map.keysIterator
( ).
// map.map(_._2) map.map(_._2).toIterator // map.values map.valuesIterator
( ).
filterKeys
// map.filterKeys(p) // map.filter(p(_._1))
filterKeys
- . , filterKeys
. , , , , filterKeys(p).groupBy(???)
.
«» ( , ) â , - .
filterKeys
, , , - , . withKeyFilter
( withFilter
).
, .
, filterKeys
( , ), .
, , ( ) , , :
type MapView[A, +B] = Map[A, B] implicit class MapExt[A, +B](val map: Map[A, B]) extends AnyVal { def withKeyFilter(p: A => Boolean): MapView[A, B] = map.filterKeys(p) }
MapView
, , view-. :
def get(k: T) = if (p(k)) map.get(k) else None
mapValues
// map.mapValues(f) // map.map(f(_._2))
, . :
type MapView[A, +B] = Map[A, B] implicit class MapExt[A, +B](val map: Map[A, B]) extends AnyVal { def withValueMapper[C](f: B => C): MapView[A, C] = map.mapValues(f) }
:
def get(k: T) = map.get(k).map(f)
// map.filterKeys(!seq.contains(_)) // map
, .
// map = map + x -> y map1 = map1 ++ map2 map = map - x map = map -- seq // map += x -> y map1 ++= map2 map -= x map --= seq
, , .
8.
Scala , .
:
Scala.
, . , - , . .
翻蚳è
ãã
. ( ). firegurafiku , .