6

This is the code that I currently use

val bytes = new Array[Byte](20)
scala.util.Random.nextBytes(bytes)
sendAndReceive(bytes)

Is there a way to turn that into a one-liner? For example, if it is an Integer array I can do

sendAndReceive(Array.fill(20){scala.util.Random.nextInt(9)}

Replacing nextInt with nextBytes does not work because nextBytes takes an Array[Byte] as parameter, instead of returning a single Byte.

Hanxue
  • 12,243
  • 18
  • 88
  • 130

2 Answers2

11

How about manually doing it? Byte range is from -128 to 127. That gives us:

Array.fill(20)((scala.util.Random.nextInt(256) - 128).toByte)

You can also write an implicit if you need it at multiple places.

implicit class ExtendedRandom(ran: scala.util.Random) {
  def nextByte = (ran.nextInt(256) - 128).toByte
}

Array.fill(20)(scala.util.Random.nextByte)

As @Chris Martin suggested, you can also use nextBytes in an implicit class.

implicit class ExtendedRandom(ran: scala.util.Random) {
  def nextByteArray(size: Int) = {
    val arr = new Array[Byte](size)
    ran.nextBytes(arr)
    arr
  }
}

scala.util.Random.nextByteArray(20)
Kigyo
  • 5,668
  • 1
  • 20
  • 24
  • If you're going to use an implicit class, why would you still avoid `Random.nextBytes`? – Chris Martin Jun 17 '14 at 05:19
  • @ChrisMartin true, I'll add that. – Kigyo Jun 17 '14 at 05:25
  • Am looking at a one-liner, if possible :) – Hanxue Jun 17 '14 at 05:27
  • @hanxue My first solution is a one-liner. The other two are implicits that you define seperatly and just have to import where needed. Then the solutions are also one-liners. This is useful when you need them at multiple places. – Kigyo Jun 17 '14 at 05:29
7

There's the Kestrel combinator:

def kestrel[A](x: A)(f: A => Unit): A = { f(x); x }

With it you can write:

sendAndReceive(kestrel(Array.fill[Byte](20)(0))(Random.nextBytes))
Community
  • 1
  • 1
Chris Martin
  • 30,334
  • 10
  • 78
  • 137