Extract string of "length x breadth" into different arrays - arrays

I have a string with with multiple length and breadth in the format length x breadth separated by commas like
300x250, 720x220, 560x80
I will like to convert this into two separate arrays one containing only length and another only breadth.
Expected output
length = Array(300,720, 560)
breadth = Array(250, 220, 80)
Any novel way to achieve it?

Using unzip over tupled values, as follows,
val dims = "300x250, 720x220, 560x80"
dims.split("\\W+").map {
s => val Array(a,b,_*) = s.split("x")
(a.toInt,b.toInt) }.unzip
Note the first split fetches words without need for trimming additional blank characters. In the second split we extract the first and second elements of the resulting Array.

try this
scala> "300x250, 720x220, 560x80"
res0: String = 300x250, 720x220, 560x80
scala> res0.split(", ").map(_.split("x")(0).toInt)
res1: Array[Int] = Array(300, 720, 560)
scala> res0.split(", ").map(_.split("x")(1).toInt)
res2: Array[Int] = Array(250, 220, 80)

val str = "300x250, 720x220, 560x80"
val regex = "(\\d+)x(\\d+)".r
val result = for {
pair <- str.split(",\\s+").toList
m <- regex.findAllMatchIn(pair)
} yield (m.group(1).toInt, m.group(2).toInt)
val (length, breadth) = result.unzip

Related

Scala Multi Dimensional Array

I have the following two arrays
val a = Array(1,2)
val b = Array(0,a)
println(b(1)(0)) //'Any' does not take parameters
In the above example I can't index the value in the second array as '(0)' is not allowed. The expected result should print the value 1.
Is this possible?
Any help would be appreciated!!
The Multi-Dimensional Array is an array with more than two dimensions. In a matrix, the two dimensions are represented by rows and columns.
val a = Array(1, 2)
val b: Array[Any] = Array(0, a)
println(b(1)(0)) //'Any' does not take parameters. since b is not a valid Multi-Dimensional Array
val aa = Array(3, 4)
val c: Array[Array[Int]] = Array(aa, a) //Valid Multi-Dimensional Array
println(c(1)(0))

What is the best way to convert a scala array of strings to a map?

I have a array of strings which are delimited by a tab char ('\t'), after splitting by '\t' the second element is delimited by a ',' which are just a bunch of floats. What is a concise way to convert this string to a map?
val values = List("abc\t1,.2,.4", "def\t6,.2,2.4")
Map[String,Array[Float]] = Map{
"abc": [1,.2,.4],
"def": [6,.2,2.4]
}
Here's something that will work. Not a lot of checking for size or valid input so you'll have to add that yourself:
values.map{x =>
x.split("\t").toList match {
case x :: y :: Nil => (x -> y.split(",").map(_.toFloat).toList)}
}.toMap
Output:
res0: scala.collection.immutable.Map[String,List[Float]] = Map(abc -> List(1.0, 0.2, 0.4), def -> List(6.0, 0.2, 2.4))
I got it working by doing below.
values.map(i => i.split('\t')).map(i => (i(0),i(1).split(',').map(_.toFloat))).toMap
output:
res30: scala.collection.immutable.Map[String,Array[Float]]
I think this is a fairly straightforward approach:
val input = List("abc\t1,.2,.4", "def\t6,.2,2.4")
/* Split the strings into (k,v) tuples, (v is still a string) */
val split = input.map(x => {val spl = x.split("\t"); (spl(0), spl(1))})
/* Split the v's into a float array, transform (k,v) list into a map */
val output = split.map(x => (x._1, x._2.split(",").map(_.toFloat))).toMap
(the lines are split up for clarity)

How to find a substring in an array of strings in matlab?

I have a string 'ADSL'. I want to find this string in an array of strings char('PSTN,ADSL','ADSL,VDSL','FTTH,VDSL')
when i run this command
strmatch('ADSL',char('PSTN,ADSL','ADSL,VDSL','FTTH,VDSL'));
the output is 2
But I expect the output as [1 2]
strmatch only gives positive result if the search string appears at the begining of row.
How can I find the search string if it occurs anywhere in the row?
Given the following input:
array = {'PSTN,ADSL', 'ADSL,VDSL', 'FTTH,VDSL'};
str = 'ADSL';
We find the starting position of each string match using:
>> pos = strfind(array, str)
pos =
[6] [1] []
or
>> pos = regexp(array, str)
pos =
[6] [1] []
We can then find the indices of matching strings using:
>> matches = find(~cellfun(#isempty,pos))
matches =
1 2
For an array of strings, it's better to use a cell array. That way strings can be of differnet lengths (and regexp can be applied on all cells at once):
cellArray = {'PSTN,ADSL','ADSL,VDSL','FTTH,VDSL'};
str = 'ADSL';
Then:
result = find(~cellfun('isempty', regexp(cellArray, str)));
will give what you want.
If you really have a char array as in your example,
array = char('PSTN,ADSL','ADSL,VDSL','FTTH,VDSL');
you can convert to a cell array (with cellstr) and apply the above:
result = find(~cellfun('isempty', regexp(cellstr(array), str)));
i would use strfind
a=strfind(cellstr(char('PSTN,ADSL','ADSL,VDSL','FTTH,VDSL')),'ADSL');
in this case will be a three by one cell array containing the index where you string starts at in the corresponding string

Compare size of 2 Arrays in Scala

If I have 2 arrays, how do I compare them and return the size of the smallest one? Here is what I mean:
val a = Array(1,2,3)
val b = Array(1,2,3,4)
is there some operator that I could call to compare the sizes of both and return 3, since Array a is smaller and has 3 elements?
scala> val a = Array(1,2,3)
a: Array[Int] = Array(1, 2, 3)
scala> val b = Array(1,2,3,4)
b: Array[Int] = Array(1, 2, 3, 4)
scala> math.min(a.length, b.length)
res0: Int = 3
A more generic approach, assuming you want to compare Sequences of the same type.
def getSmallerCollectionSize[T](a:Seq[T],b:Seq[T]) =
Math.min(a.size, b.size)
scala> val a = Array(1,2,3)
a:Array[Int] = Array(1,2,3)
scala> val b = Array(1,2,3,4)
b:Array[Int] = Array(1,2,3,4)
scala> a.size min b.size
res0: Int = 3
The size method gets the size of the Array and min is a comparator function between the two sizes. As with any function taking two parameters, you can call it by putting the function name between the parameters.
min is doing an implicit conversion (a set of methods that Scala tries to apply when it encounters an object of the wrong type being used) from Int to RichInt.

strange ArrayBuffer behavior

Can someone please explain to me why the padTo method of ArrayBuffer doesn't work as I would expect it to? In this example, I would expect the array created by toArray to have a length of 10.
scala> val b = new scala.collection.mutable.ArrayBuffer[Byte]
b: scala.collection.mutable.ArrayBuffer[Byte] = ArrayBuffer()
scala> b.append(2)
scala> b
res1: scala.collection.mutable.ArrayBuffer[Byte] = ArrayBuffer(2)
scala> b.append(2)
scala> b
res3: scala.collection.mutable.ArrayBuffer[Byte] = ArrayBuffer(2, 2)
scala> b.padTo(10,0)
res4: scala.collection.mutable.ArrayBuffer[AnyVal] = ArrayBuffer(2, 2, 0, 0, 0, 0, 0, 0, 0, 0)
scala> b.toArray
res5: Array[Byte] = Array(2, 2)
Because padTo returns a new sequence (it doesn't mutate the existing one):
Try
var c = b.padTo(10,0)
c.toArray
See also: https://issues.scala-lang.org/browse/SI-2257
If you look at the documentation, you'll see the difference:
def append (elems: A*): Unit
Use case (append): Appends the given elements to this buffer.
def padTo (len: Int, elem: A): ArrayBuffer[A]
Use case (padTo): Appends an element value to this arraybuffer until a given target length is reached.
Append returns Unit, while padTo returns new ArrayBuffer.
From scaladoc:
returns: a new collection of type That consisting of all elements of
this arraybuffer followed by the minimal number of occurrences of elem
so that the resulting collection has a length of at least len.
So, b, even mutable, does not changes.

Resources