Hi I am looking for a solution it will return a substring from string for the given indexes.For avoiding index bound exception currently using if and else check.Is there a better approach(functional).
def subStringEn(input:String,start:Int,end:Int)={
// multiple if check for avoiding index out of bound exception
input.substring(start,end)
}
Not sure what you want the function to do in case of index out of bound, but slice might fit your needs:
input.slice(start, end)
Some examples:
scala> "hello".slice(1, 2)
res6: String = e
scala> "hello".slice(1, 30)
res7: String = ello
scala> "hello".slice(7, 8)
res8: String = ""
scala> "hello".slice(0, 5)
res9: String = hello
Try is one way of doing it. The other way is applying substring only if length is greater than end using Option[String].
invalid end index
scala> val start = 1
start: Int = 1
scala> val end = 1000
end: Int = 1000
scala> Option("urayagppd").filter(_.length > end).map(_.substring(start, end))
res9: Option[String] = None
valid end index
scala> val end = 6
end: Int = 6
scala> Option("urayagppd").filter(_.length > end).map(_.substring(start, end))
res10: Option[String] = Some(rayag)
Also, you can combine filter and map to .collect as below,
scala> Option("urayagppd").collect { case x if x.length > end => x.substring(start, end) }
res14: Option[String] = Some(rayag)
scala> val end = 1000
end: Int = 1000
scala> Option("urayagppd").collect { case x if x.length > end => x.substring(start, end) }
res15: Option[String] = None
Related
I am using
val str2 = regex.replaceAllIn(str1, "other")
and need to count the number of replaces... There are a way retrieve the value of the internal replaceAllIn counter?
PS: this is usual in other languages (example), so I am supposing that Scala offer similar thing.
scala> val r = "x".r
r: scala.util.matching.Regex = x
scala> var i = 0
i: Int = 0
scala> r.replaceAllIn("xooxxox", m => { i += 1 ; "X" })
res0: String = XooXXoX
scala> i
res1: Int = 4
will do appendReplacement under the hood.
Takes another step but you could findAllIn and count the number found. Then do replaceAllIn.
scala> "foo".r.findAllIn("barbazfoobazfoo").size
res7: Int = 2
I'm pretty new of Scala, and I know there must be a nice way to do this, but I can't come up with something nice and readable.
I have a set of ids (strings), and for each id, I run some function that returns a boolean.
The result is a Set[Boolean], but I want to create a tuple containing two numbers, one is the number of true and one is the number of false.
What's a clean/readable way to do this?
Given your ids and f:
val ids: Set[String] = ???
def f(s: String): Boolean = ???
The following gets you there fairly concisely using the built-in partition function:
val (trues, falses) = ids partition f
(trues.size, falses.size)
You can utilize the count method of a Seq:
val ids: Seq[String] = Seq("1", "12", "3")
def containsOne(s: String) = s.contains('1')
val processedIds = ids.map(containsOne)
// first item is amount of trues, second is amount of falses
val count: (Int, Int) = (processedIds.count(identity), processedIds.count(_ == false))
You must use a Seq as a Set will 'flatten' out the collection of Boolean (to a maximum size of 2, no duplicates allowed).
Here's an expression that counts the number of even elements and odd elements in the set:
Set(3,4,5,6,8,3).toSeq.map{_ % 2 == 0}
.foldLeft((0,0)){(t,c) => if (c) (t._1+1, t._2) else (t._1, t._2+1)}
The toSeq is necessary to keep the output of map from being just a Set.
Just replace {_ % 2 == 0} with a call to your function.
Given your fn,
scala> def fn(x: String) = x.contains("customer")
fn: (x: String)Boolean
you have to .map to create boolean -> Set(Id), then aggregate by boolean, then count how many IDs for each boolean
scala> Set("customerId-1", "customerId-2", "id-3", "id-4")
.map(x => fn(x) -> x)
.groupBy(_._1)
.map { case (boolean, set) => boolean -> set.size }
res51: scala.collection.immutable.Map[Boolean,Int] = Map(false -> 2, true -> 2)
Here's my attempt at a one-liner (except that it doesn't fit on one line in this little box:(
My test function is true if division by 3 leaves a remainder of 1, and false otherwise, and I'm running it on the range 1 to 6 (i.e., 1,2,3,4,5):
scala> val x = (1 to 6).partition(_%3 == 1) match
| { case (s1,s2) => (s1.length, s2.length) }
x: (Int, Int) = (2,4)
And so, writing the main function in a little more generality,
scala> def boolCounter[T](
| s: Seq[T],
| f: T => Boolean): (Integer, Integer) =
| s.partition(f) match { case (s1, s2) => (s1.length, s2.length) }
boolCounter: [T](s: Seq[T], f: T => Boolean)(Integer, Integer)
scala> val r = 1 to 6
r: scala.collection.immutable.Range.Inclusive = Range 1 to 6
scala> val f: Int => Boolean = { x => x%3 == 1}
f: Int => Boolean = $$Lambda$1252/1891031939#5a090f62
scala> boolCounter(r, f)
res0: (Integer, Integer) = (2,4)
// when in Scala REPL
scala> 1
res0: Int = 1
How can I reuse an expression's result in another expression?
For example:
scala> 1
res0: Int = 1
scala> the_previous_expression + 1
// = 2
You can reuse the previous expression's result by looking its REPL output on the next line, the word starting with res.
// when in Scala REPL
scala> 1
res0: Int = 1 // <-- res0 is the handle that you can use
For example:
scala> 1
res0: Int = 1
scala> res0 + 1
res1: Int = 2
scala> res1 + 1
res2: Int = 3
// and so on
You can also use it with others:
scala> () => "hey!" // anonymous function
res0: () => String = $$Lambda$1104/1658578510#6cff61fc
scala> res0()
res1: String = hey
For a Scala List[Int] I can call the method max to find the maximum element value.
How can I find the index of the maximum element?
This is what I am doing now:
val max = list.max
val index = list.indexOf(max)
One way to do this is to zip the list with its indices, find the resulting pair with the largest first element, and return the second element of that pair:
scala> List(0, 43, 1, 34, 10).zipWithIndex.maxBy(_._1)._2
res0: Int = 1
This isn't the most efficient way to solve the problem, but it's idiomatic and clear.
Since Seq is a function in Scala, the following code works:
list.indices.maxBy(list)
even easier to read would be:
val g = List(0, 43, 1, 34, 10)
val g_index=g.indexOf(g.max)
def maxIndex[ T <% Ordered[T] ] (list : List[T]) : Option[Int] = list match {
case Nil => None
case head::tail => Some(
tail.foldLeft((0, head, 1)){
case ((indexOfMaximum, maximum, index), elem) =>
if(elem > maximum) (index, elem, index + 1)
else (indexOfMaximum, maximum, index + 1)
}._1
)
} //> maxIndex: [T](list: List[T])(implicit evidence$2: T => Ordered[T])Option[Int]
maxIndex(Nil) //> res0: Option[Int] = None
maxIndex(List(1,2,3,4,3)) //> res1: Option[Int] = Some(3)
maxIndex(List("a","x","c","d","e")) //> res2: Option[Int] = Some(1)
maxIndex(Nil).getOrElse(-1) //> res3: Int = -1
maxIndex(List(1,2,3,4,3)).getOrElse(-1) //> res4: Int = 3
maxIndex(List(1,2,2,1)).getOrElse(-1) //> res5: Int = 1
In case there are multiple maximums, it returns the first one's index.
Pros:You can use this with multiple types, it goes through the list only once, you can supply a default index instead of getting exception for empty lists.
Cons:Maybe you prefer exceptions :) Not a one-liner.
I think most of the solutions presented here go thru the list twice (or average 1.5 times) -- Once for max and the other for the max position. Perhaps a lot of focus is on what looks pretty?
In order to go thru a non empty list just once, the following can be tried:
list.foldLeft((0, Int.MinValue, -1)) {
case ((i, max, maxloc), v) =>
if (v > max) (i + 1, v, i)
else (i + 1, max, maxloc)}._3
Pimp my library! :)
class AwesomeList(list: List[Int]) {
def getMaxIndex: Int = {
val max = list.max
list.indexOf(max)
}
}
implicit def makeAwesomeList(xs: List[Int]) = new AwesomeList(xs)
//> makeAwesomeList: (xs: List[Int])scalaconsole.scratchie1.AwesomeList
//Now we can do this:
List(4,2,7,1,5,6) getMaxIndex //> res0: Int = 2
//And also this:
val myList = List(4,2,7,1,5,6) //> myList : List[Int] = List(4, 2, 7, 1, 5, 6)
myList getMaxIndex //> res1: Int = 2
//Regular list methods also work
myList filter (_%2==0) //> res2: List[Int] = List(4, 2, 6)
More details about this pattern here: http://www.artima.com/weblogs/viewpost.jsp?thread=179766
I'm new to scala, and what I'm learning is tuple.
I can define a tuple as following, and get the items:
val tuple = ("Mike", 40, "New York")
println("Name: " + tuple._1)
println("Age: " + tuple._2)
println("City: " + tuple._3)
My question is:
How to get the length of a tuple?
Is tuple mutable? Can I modify its items?
Is there any other useful operation we can do on a tuple?
Thanks in advance!
1] tuple.productArity
2] No.
3] Some interesting operations you can perform on tuples: (a short REPL session)
scala> val x = (3, "hello")
x: (Int, java.lang.String) = (3,hello)
scala> x.swap
res0: (java.lang.String, Int) = (hello,3)
scala> x.toString
res1: java.lang.String = (3,hello)
scala> val y = (3, "hello")
y: (Int, java.lang.String) = (3,hello)
scala> x == y
res2: Boolean = true
scala> x.productPrefix
res3: java.lang.String = Tuple2
scala> val xi = x.productIterator
xi: Iterator[Any] = non-empty iterator
scala> while(xi.hasNext) println(xi.next)
3
hello
See scaladocs of Tuple2, Tuple3 etc for more.
One thing that you can also do with a tuple is to extract the content using the match expression:
def tupleview( tup: Any ){
tup match {
case (a: String, b: String) =>
println("A pair of strings: "+a + " "+ b)
case (a: Int, b: Int, c: Int) =>
println("A triplet of ints: "+a + " "+ b + " " +c)
case _ => println("Unknown")
}
}
tupleview( ("Hello", "Freewind"))
tupleview( (1,2,3))
Gives:
A pair of strings: Hello Freewind
A triplet of ints: 1 2 3
Tuples are immutable, but, like all cases classes, they have a copy method that can be used to create a new Tuple with a few changed elements:
scala> (1, false, "two")
res0: (Int, Boolean, java.lang.String) = (1,false,two)
scala> res0.copy(_2 = true)
res1: (Int, Boolean, java.lang.String) = (1,true,two)
scala> res1.copy(_1 = 1f)
res2: (Float, Boolean, java.lang.String) = (1.0,true,two)
Concerning question 3:
A useful thing you can do with Tuples is to store parameter lists for functions:
def f(i:Int, s:String, c:Char) = s * i + c
List((3, "cha", '!'), (2, "bora", '.')).foreach(t => println((f _).tupled(t)))
//--> chachacha!
//--> borabora.
[Edit] As Randall remarks, you'd better use something like this in "real life":
def f(i:Int, s:String, c:Char) = s * i + c
val g = (f _).tupled
List((3, "cha", '!'), (2, "bora", '.')).foreach(t => println(g(t)))
In order to extract the values from tuples in the middle of a "collection transformation chain" you can write:
val words = List((3, "cha"),(2, "bora")).map{ case(i,s) => s * i }
Note the curly braces around the case, parentheses won't work.
Another nice trick ad question 3) (as 1 and 2 are already answered by others)
val tuple = ("Mike", 40, "New York")
tuple match {
case (name, age, city) =>{
println("Name: " + name)
println("Age: " + age)
println("City: " + city)
}
}
Edit: in fact it's rather a feature of pattern matching and case classes, a tuple is just a simple example of a case class...
You know the size of a tuple, it's part of it's type. For example if you define a function def f(tup: (Int, Int)), you know the length of tup is 2 because values of type (Int, Int) (aka Tuple2[Int, Int]) always have a length of 2.
No.
Not really. Tuples are useful for storing a fixed amount of items of possibly different types and passing them around, putting them into data structures etc. There's really not much you can do with them, other than creating tuples, and getting stuff out of tuples.
1 and 2 have already been answered.
A very useful thing that you can use tuples for is to return more than one value from a method or function. Simple example:
// Get the min and max of two integers
def minmax(a: Int, b: Int): (Int, Int) = if (a < b) (a, b) else (b, a)
// Call it and assign the result to two variables like this:
val (x, y) = minmax(10, 3) // x = 3, y = 10
Using shapeless, you easily get a lot of useful methods, that are usually available only on collections:
import shapeless.syntax.std.tuple._
val t = ("a", 2, true, 0.0)
val first = t(0)
val second = t(1)
// etc
val head = t.head
val tail = t.tail
val init = t.init
val last = t.last
val v = (2.0, 3L)
val concat = t ++ v
val append = t :+ 2L
val prepend = 1.0 +: t
val take2 = t take 2
val drop3 = t drop 3
val reverse = t.reverse
val zip = t zip (2.0, 2, "a", false)
val (unzip, other) = zip.unzip
val list = t.toList
val array = t.toArray
val set = t.to[Set]
Everything is typed as one would expect (that is first has type String, concat has type (String, Int, Boolean, Double, Double, Long), etc.)
The last method above (.to[Collection]) should be available in the next release (as of 2014/07/19).
You can also "update" a tuple
val a = t.updatedAt(1, 3) // gives ("a", 3, true, 0.0)
but that will return a new tuple instead of mutating the original one.