This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Using arrays in Scala

8 replies
Calum
Joined: 2009-02-20,
User offline. Last seen 42 years 45 weeks ago.

Hi

I'm trying to work out how to best use arrays in Scala, or see if there's a
better equivalent for my purposes. [BTW, I'm quite new to Scala...]

I have a data object which should have an immutable sequence of bytes, with
random access, as one of its members.
Currently, I'm using a case class, which has a member which is an
Array[Byte] (which is more-or-less a direct translation of the equivalent
byte[] in Java). I've come across some problems doing this, and would
appreciate some comments on the best approach.
Should I be using Array, or a different collection class?

Here are a couple of the problems I'm having with Array:
1) Arrays are mutable; I want an immutable sequence.
2) Array#equals() uses reference equality; I want to compare based on the
contents.

Also, in my unit tests, I want to create some Array[Byte] instances. What's
the best way to do this? If I use Array(0x3A, 0xBC), I get an Array[Int],
which is not what I want.
What's the easiest way to get Byte literals? In Java, it would be
(byte)0xBC; in Scala, the equivalent seems to be 0xBC.asInstanceOf[Byte],
which is obviously even more verbose than Java.
Should I just be defining a convenience method similar to that below?
def apply(parts: Int*): Array[Byte] = {
parts.map(a => a.asInstanceOf[Byte]).toArray
}

Thanks for your help,
Calum

David Hall 3
Joined: 2009-02-19,
User offline. Last seen 42 years 45 weeks ago.
Re: Using arrays in Scala

On Fri, Feb 20, 2009 at 9:46 AM, Calum wrote:
>
> Hi
>
> I'm trying to work out how to best use arrays in Scala, or see if there's a
> better equivalent for my purposes. [BTW, I'm quite new to Scala...]
>
> I have a data object which should have an immutable sequence of bytes, with
> random access, as one of its members.
> Currently, I'm using a case class, which has a member which is an
> Array[Byte] (which is more-or-less a direct translation of the equivalent
> byte[] in Java). I've come across some problems doing this, and would
> appreciate some comments on the best approach.
> Should I be using Array, or a different collection class?

(Short answer: an ArrayBuffer[Byte] that's been cast to a Seq[Byte] )

>
> Here are a couple of the problems I'm having with Array:
> 1) Arrays are mutable; I want an immutable sequence.

Cast the array to a Seq[Byte]?

> 2) Array#equals() uses reference equality; I want to compare based on the
> contents.

Define an implicit? Use a List or ArrayBuffer?

scala> new ArrayBuffer[Int]() + 1 + 2
res12: scala.collection.mutable.Buffer[Int] = ArrayBuffer(1, 2)

scala> new ArrayBuffer[Int]() + 1 + 2
res13: scala.collection.mutable.Buffer[Int] = ArrayBuffer(1, 2)

scala> res12 == res13
res15: Boolean = true

>
> Also, in my unit tests, I want to create some Array[Byte] instances. What's
> the best way to do this? If I use Array(0x3A, 0xBC), I get an Array[Int],
> which is not what I want.
> What's the easiest way to get Byte literals? In Java, it would be
> (byte)0xBC; in Scala, the equivalent seems to be 0xBC.asInstanceOf[Byte],
> which is obviously even more verbose than Java.
> Should I just be defining a convenience method similar to that below?
> def apply(parts: Int*): Array[Byte] = {
> parts.map(a => a.asInstanceOf[Byte]).toArray
> }

0xBC.toByte ?

It has 1 more character than "(byte)", but I contend it's easier to type. :-)

>
> Thanks for your help,
> Calum
> --
> View this message in context: http://www.nabble.com/Using-arrays-in-Scala-tp22125306p22125306.html
> Sent from the Scala - User mailing list archive at Nabble.com.
>
>

Victor Mateus O...
Joined: 2009-02-09,
User offline. Last seen 42 years 45 weeks ago.
Re: Using arrays in Scala
Hi,

You can force the type at variable declaration:
val foo: Array[Byte] = Array(0x12, 0x13, 0x14)

[]s
Victor

On Fri, Feb 20, 2009 at 2:46 PM, Calum <cnmaclean@hotmail.com> wrote:

Hi

I'm trying to work out how to best use arrays in Scala, or see if there's a
better equivalent for my purposes. [BTW, I'm quite new to Scala...]

I have a data object which should have an immutable sequence of bytes, with
random access, as one of its members.
Currently, I'm using a case class, which has a member which is an
Array[Byte] (which is more-or-less a direct translation of the equivalent
byte[] in Java). I've come across some problems doing this, and would
appreciate some comments on the best approach.
Should I be using Array, or a different collection class?

Here are a couple of the problems I'm having with Array:
1) Arrays are mutable; I want an immutable sequence.
2) Array#equals() uses reference equality; I want to compare based on the
contents.

Also, in my unit tests, I want to create some Array[Byte] instances. What's
the best way to do this? If I use Array(0x3A, 0xBC), I get an Array[Int],
which is not what I want.
What's the easiest way to get Byte literals? In Java, it would be
(byte)0xBC; in Scala, the equivalent seems to be 0xBC.asInstanceOf[Byte],
which is obviously even more verbose than Java.
Should I just be defining a convenience method similar to that below?
 def apply(parts: Int*): Array[Byte] = {
   parts.map(a => a.asInstanceOf[Byte]).toArray
 }

Thanks for your help,
Calum
--
View this message in context: http://www.nabble.com/Using-arrays-in-Scala-tp22125306p22125306.html
Sent from the Scala - User mailing list archive at Nabble.com.




--
GNU/Linux user #5f5f5f - http://counter.li.org
Rich Dougherty 2
Joined: 2009-01-19,
User offline. Last seen 42 years 45 weeks ago.
Re: Using arrays in Scala

On Sat, Feb 21, 2009 at 6:46 AM, Calum wrote:
> Here are a couple of the problems I'm having with Array:
> 1) Arrays are mutable; I want an immutable sequence.
> 2) Array#equals() uses reference equality; I want to compare based on the
> contents.

Hi Calum

You may be interested in an immutable byte array implementation that
is used in the Scala OTP libraries. It satisfies your requirements
above. It is designed to support IO, which involves a lot of
concatenation and sequential access, so it is implemented as a rope:
http://en.wikipedia.org/wiki/Rope_(computer_science).

Here is some example usage. (Please excuse the fact that the library
is abusing the scala namespace!)

scala> import scala.binary.Binary
import scala.binary.Binary

scala> val a = Binary(1, 2, 3)
a: scala.binary.Binary = Binary(1, 2, 3)

scala> a.toArray
res0: Array[Byte] = Array(1, 2, 3)

scala> val b = Binary(1, 2, 3)
b: scala.binary.Binary = Binary(1, 2, 3)

scala> a == b
res1: Boolean = true

scala> b(0)
res2: Byte = 1

scala> val c = Binary.fromString("Hello world!", "utf8")
c: scala.binary.Binary = Binary(72, 101, 108, 108, 111, 32, 119, 111,
114, 108, 100, 33)

scala> val l = List(1, 2, 3) map { _.asInstanceOf[Byte] }
l: List[Byte] = List(1, 2, 3)

scala> val d = Binary.fromArray(l.toArray)
d: scala.binary.Binary = Binary(1, 2, 3)

scala> a == d
res3: Boolean = true

scala> val e = Binary.fromSeq(l)
e: scala.binary.Binary = Binary(1, 2, 3)

scala> a ++ b ++ c ++ d ++ e
res4: scala.binary.Binary = Binary(1, 2, 3, 1, 2, 3, 72, 101, 108,
108, 111, 32, 119, 111, 114, 108, [8 more])

Nightly builds are available from
http://scala-tools.org/repo-snapshots/org/scala-libs/scala-otp-binary/0.....
The source is available from
http://github.com/jboner/scala-otp/tree/master.

Cheers
Rich

--
http://www.richdougherty.com/

Naftoli Gugenheim
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Re: Using arrays in Scala

You don't need asInstanceOf or toByte. scala> Array(0x12: Byte)
res0: Array[Byte] ...

On 2/20/09, Rich Dougherty wrote:
> On Sat, Feb 21, 2009 at 6:46 AM, Calum wrote:
>> Here are a couple of the problems I'm having with Array:
>> 1) Arrays are mutable; I want an immutable sequence.
>> 2) Array#equals() uses reference equality; I want to compare based on the
>> contents.
>
> Hi Calum
>
> You may be interested in an immutable byte array implementation that
> is used in the Scala OTP libraries. It satisfies your requirements
> above. It is designed to support IO, which involves a lot of
> concatenation and sequential access, so it is implemented as a rope:
> http://en.wikipedia.org/wiki/Rope_(computer_science).
>
> Here is some example usage. (Please excuse the fact that the library
> is abusing the scala namespace!)
>
> scala> import scala.binary.Binary
> import scala.binary.Binary
>
> scala> val a = Binary(1, 2, 3)
> a: scala.binary.Binary = Binary(1, 2, 3)
>
> scala> a.toArray
> res0: Array[Byte] = Array(1, 2, 3)
>
> scala> val b = Binary(1, 2, 3)
> b: scala.binary.Binary = Binary(1, 2, 3)
>
> scala> a == b
> res1: Boolean = true
>
> scala> b(0)
> res2: Byte = 1
>
> scala> val c = Binary.fromString("Hello world!", "utf8")
> c: scala.binary.Binary = Binary(72, 101, 108, 108, 111, 32, 119, 111,
> 114, 108, 100, 33)
>
> scala> val l = List(1, 2, 3) map { _.asInstanceOf[Byte] }
> l: List[Byte] = List(1, 2, 3)
>
> scala> val d = Binary.fromArray(l.toArray)
> d: scala.binary.Binary = Binary(1, 2, 3)
>
> scala> a == d
> res3: Boolean = true
>
> scala> val e = Binary.fromSeq(l)
> e: scala.binary.Binary = Binary(1, 2, 3)
>
> scala> a ++ b ++ c ++ d ++ e
> res4: scala.binary.Binary = Binary(1, 2, 3, 1, 2, 3, 72, 101, 108,
> 108, 111, 32, 119, 111, 114, 108, [8 more])
>
> Nightly builds are available from
> http://scala-tools.org/repo-snapshots/org/scala-libs/scala-otp-binary/0.....
> The source is available from
> http://github.com/jboner/scala-otp/tree/master.
>
> Cheers
> Rich
>
> --
> http://www.richdougherty.com/
>

Calum
Joined: 2009-02-20,
User offline. Last seen 42 years 45 weeks ago.
Re: Using arrays in Scala

Hi Naftoli

That only works if the value is between -128 and 127:

scala> Array(0xA4: Byte)
:5: error: type mismatch;
found : Int(164)
required: Byte
Array(0xA4: Byte)

So I want to be able to specify the byte values as hex, meaning they're
values between 0 and 255 (decimal).

Calling toByte seems the best way.

Thanks,
Calum

Naftoli Gugenheim wrote:
>
> You don't need asInstanceOf or toByte. scala> Array(0x12: Byte)
> res0: Array[Byte] ...
>

Ricky Clarkson
Joined: 2008-12-19,
User offline. Last seen 3 years 2 weeks ago.
Re: Using arrays in Scala
List(0xFF, 0x80, 0xCABBA6E) map (_ toByte)

2009/2/24 Calum <cnmaclean@hotmail.com>

Hi Naftoli

That only works if the value is between -128 and 127:

scala> Array(0xA4: Byte)
<console>:5: error: type mismatch;
 found   : Int(164)
 required: Byte
      Array(0xA4: Byte)

So I want to be able to specify the byte values as hex, meaning they're
values between 0 and 255 (decimal).

Calling toByte seems the best way.

Thanks,
Calum


Naftoli Gugenheim wrote:
>
> You don't need asInstanceOf or toByte.  scala> Array(0x12: Byte)
> res0: Array[Byte] ...
>

--
View this message in context: http://www.nabble.com/Using-arrays-in-Scala-tp22125306p22181065.html
Sent from the Scala - User mailing list archive at Nabble.com.


DRMacIver
Joined: 2008-09-02,
User offline. Last seen 42 years 45 weeks ago.
Re: Using arrays in Scala

On Tue, 24 Feb 2009, Calum wrote:

>
> Hi Naftoli
>
> That only works if the value is between -128 and 127:

I wonder if it would be worth considering fixing that. We can't fix all of
Java's broken decisions, but allowing things like 0xFF for byte literals
seems easy to fix and very worth doing.

e.g. we could allow literals that lie in the -256 to 255 range.

Calum
Joined: 2009-02-20,
User offline. Last seen 42 years 45 weeks ago.
Re: Using arrays in Scala

David R. MacIver wrote:
>
>
> I wonder if it would be worth considering fixing that. We can't fix all of
> Java's broken decisions, but allowing things like 0xFF for byte literals
> seems easy to fix and very worth doing.
>
> e.g. we could allow literals that lie in the -256 to 255 range.
>

However, a byte value would still ultimately have a value between -128 and
127, when processed subsequently.
So it might be confusing to allow entry of byte literals over the extended
range, but the actual value is still between -128 and 127.

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland