- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Using arrays in Scala
Fri, 2009-02-20, 18:46
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
Fri, 2009-02-20, 21:17
#2
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:
--
GNU/Linux user #5f5f5f - http://counter.li.org
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
Fri, 2009-02-20, 21:57
#3
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
Mon, 2009-02-23, 20:07
#4
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/
>
Tue, 2009-02-24, 15:57
#5
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] ...
>
Tue, 2009-02-24, 16:47
#6
Re: Using arrays in Scala
List(0xFF, 0x80, 0xCABBA6E) map (_ toByte)
2009/2/24 Calum <cnmaclean@hotmail.com>
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.
Tue, 2009-02-24, 18:37
#7
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.
Tue, 2009-02-24, 19:17
#8
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.
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.
>
>