7

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.

2 Answers 2

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)
Sign up to request clarification or add additional context in comments.

4 Comments

If you're going to use an implicit class, why would you still avoid Random.nextBytes?
@ChrisMartin true, I'll add that.
Am looking at a one-liner, if possible :)
@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.
8

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))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.