SS.
SS.

Reputation: 109

More elegant scala code

I am starting to learn scala. Wonder if anyone has a better way to re-write below code in a more functional way. I know there must be one.

val buf = ((addr>>24)&0xff) + "." + ((addr>>16)&0xff) + "." + ((addr>>8)&0xff) + "." + ((addr)&0xff)

Upvotes: 3

Views: 509

Answers (4)

idonnie
idonnie

Reputation: 1713

The advantage is that input - can be ANY number of integers

// trick
implicit class When[F](fun: F) {  
  def when(cond: F => Boolean)(tail: F => F) = if (cond(fun)) tail(fun) else fun
}

// actual one-liner
12345678.toHexString.when(1 to 8 contains _.length % 8)
  (s => "0" * (8 - s.length % 8) + s ).reverse.grouped(2).map
  (Integer.parseInt(_, 16)).toList.reverse.mkString(".")

// 0.203.22.228

// a very big IPv7
BigInt("123456789012345678901").toString(16).when(1 to 8 contains _.length % 8)
  (s => "0" * (8 - s.length % 8) + s ).reverse.grouped(2).map
  (Integer.parseInt(_, 16)).toList.reverse.mkString(".")

// 0.0.0.96.27.228.249.24.242.99.198.83

EDIT

Explanation because of downvotes. implicit class When can be just a library class, it works in 2.10 and allows conditionally execute some of functions in a calls chain. I did not measure performance, and don't care, because an example itself is meant to be an illustration of what is possible, elegant or not.

Upvotes: -2

Wilfred Springer
Wilfred Springer

Reputation: 10927

Some would find the for comprehension a little bit more readable:

(for (pos <- 24 to 0 by -8) yield addr >> pos & 0xff) mkString "."

Upvotes: 2

swartzrock
swartzrock

Reputation: 729

val buf = List(24,16,8,0).map(addr >> _).map(_ & 0xff).mkString(".")

Here's how I would do it, similar to Brian's answer but with a short list of values and two simple map() methods using Scala's famous '_' operator. Great question!

Upvotes: 3

Brian
Brian

Reputation: 20295

This generates the Range(24, 16, 8, 0) with (24 to 0 by -8) and then applies the function addr >> _ & 0xff to each number using map. Lastly, the mapped Range of numbers is "joined" with . to create a string.

The map is more functional than using the + operator but the rest is just syntactic sugar and a library call to mkString.

val addr = 1024

val buf = (24 to 0 by -8).map(addr >> _ & 0xff).mkString(".")

buf: java.lang.String = 0.0.4.0

Upvotes: 11

Related Questions