scala: find the amount of a specific element in a list - scala

I want to write a function count: (List[Int]) => Int in scala which counts the amount of a specific element in a list. I want to implement it this way:
count(2, List(2, 4, 5, 2, 2, 7))
should return 3. How can I do this in scala?

List has an inbuilt count already like #Jeffery mentioned.
You asked to make it a function, so:
scala> val count = (x: Int, ls: List[Int]) => ls.count(_ == x)
count: (Int, List[Int]) => Int = <function2>
scala> count(2, List(2,4,5,2,2,7))
res1: Int = 3

Related

How to calculate length of string in a tuple in scala

Given a list of tuples, where the 1st element of the tuple is an integer and the second element is a string,
scala> val tuple2 : List[(Int,String)] = List((1,"apple"),(2,"ball"),(3,"cat"),(4,"doll"),(5,"eggs"))
tuple2: List[(Int, String)] = List((1,apple), (2,ball), (3,cat), (4,doll), (5,eggs))
I want to print the numbers where the corresponding string length is 4.
Can this be done in one line ?
you need .collect which is filter+map
given your input,
scala> val input : List[(Int,String)] = List((1,"apple"),(2,"ball"),(3,"cat"),(4,"doll"),(5,"eggs"))
input: List[(Int, String)] = List((1,apple), (2,ball), (3,cat), (4,doll), (5,eggs))
filter those of length 4,
scala> input.collect { case(number, string) if string.length == 4 => number}
res2: List[Int] = List(2, 4, 5)
alternative solution using filter + map,
scala> input.filter { case(number, string) => string.length == 4 }
.map { case (number, string) => number}
res4: List[Int] = List(2, 4, 5)
you filter and print as below
tuple2.filter(_._2.length == 4).foreach(x => println(x._1))
You should have output as
2
4
5
I like #prayagupd answer using collect. But foldLeft is the one of my favourite function in Scala! you can use foldLeft:
scala> val input : List[(Int,String)] = List((1,"apple"),(2,"ball"),(3,"cat"),(4,"doll"),(5,"eggs"))
input: List[(Int, String)] = List((1,apple), (2,ball), (3,cat), (4,doll), (5,eggs))
scala> input.foldLeft(List.empty[Int]){case (acc, (n,str)) => if(str.length ==4) acc :+ n else acc}
res3: List[Int] = List(2, 4, 5)
Using a for comprehension as follows,
for ((i,s) <- tuple2 if s.size == 4) yield i
which for the example above delivers
List(2, 4, 5)
Note we pattern match and extract the elements in each tuple and filter by string size. To print a list consider for instance aList.foreach(println).
This will do:
tuple2.filter(_._2.size==4).map(_._1)
In Scala REPL:
scala> val tuple2 : List[(Int,String)] = List((1,"apple"),(2,"ball"),(3,"cat"),(4,"doll"),(5,"eggs"))
tuple2: List[(Int, String)] = List((1,apple), (2,ball), (3,cat), (4,doll), (5,eggs))
scala> tuple2.filter(_._2.size==4).map(_._1)
res261: List[Int] = List(2, 4, 5)
scala>

How to get max and min values of an Array of Tuples

Say I have a List of Tuples of Integers
var i = Array(1->3, 5->9, 15->18)
How can I return a Tuple of the highest and lowest values from the above?
So for the above input, 1-> 18 should be returned as 1 is the lowest and 18 is the highest value. Here's the skeleton of the function that takes an Array of Tuples and returns the highest & the lowest values as a Tuple.
def returnHighest(i: Array[(Int, Int)]): (Int, Int)={
....
}
Lot's of ways to do this of course. Here is one:
val i = Array(1->3, 5->9, 15->18)
i: Array[(Int, Int)] = Array((1,3), (5,9), (15,18))
scala> val flatI = i.flatMap{case(a,b) => List(a, b)}
flatI: Array[Int] = Array(1, 3, 5, 9, 15, 18)
scala> flatI.min -> flatI.max
res3: (Int, Int) = (1,18)
You could use foldLeft, but you need to be careful about the start value. What if the array is empty ?
val res4 = Array(1->3, 5->9, 15->18)
res4.foldLeft(res4(0))({
case (acc, i) =>
Math.min(acc._1, i._1) -> Math.max(acc._2, i._2)
})
res6: (Int, Int) = (1, 18)

Scala: partitioning number into n almost equal-length ranges

I am trying to implement a function:
def NumberPartition(InputNum:Int,outputListSize:Int):List[Range]
such that:
NumberPartition(8,3)=List(Range(0,3),Range(3,6),Range(6,8))
ie. it creates n-1 equal-length ranges(length=ceil(InputNum/outputListSize)) plus the last/first one being slightly smaller.
I want to use this function for agglomeration of an embarrassingly-parallel program consisting of n subroutines that are going to be batch-handled by n tasks/threads.
What is the most idiomatic way of doing this in Scala?
I think using Range steps could be helpful:
def rangeHeads(n:Int,len:Int):Range=Range(0,n,ceil(n/len))//type conversion for ceil() omitted here.
rangeHeads(8,3)//Range(0, 3, 6)
I just need a function that does (1,2,3,4)->((1,2),(2,3),(3,4))
While this isn't the exact output you are seeking, perhaps this will be good guidance:
scala> def numberPartition(inputNum: Int, outputListSize: Int): List[List[Int]] = {
(0 to inputNum).toList.grouped(outputListSize).toList
}
numberPartition: numberPartition[](val inputNum: Int,val outputListSize: Int) => List[List[Int]]
scala> numberPartition(8, 3)
res0: List[List[Int]] = List(List(0, 1, 2), List(3, 4, 5), List(6, 7, 8))
def roundedUpIntDivide(a:Int,b:Int):Int=a/b + (if(a%b==0) 0 else 1)
def partitionToRanges(n:Int,len:Int): List[(Int, Int)] ={
(Range(0,n,roundedUpIntDivide(n,len)):+n)
.sliding(2)
.map(x => (x(0),x(1)))
.toList
}
thanks to #jwvh for suggesting sliding()
def numberPartition(inputNum: Int, outputListSize: Int): List[(Int, Int)] = {
val range = 0.until(inputNum).by(inputNum/outputListSize + 1).:+(inputNum)
range.zip(range.tail).toList
}
Note:
0.until(inputNum) is an exclusive range [0, inputNum);
.by(inputNum/outputListSize + 1) is the step;
.:+(inputNum) it adds back the range upper bound;
range.zip(range.tail) build couples from list, equals to .sliding(2).map { case Seq(x,y) => (x,y) }

What is the structure that is only enclosed by parentheses in scala?

Here's the problem:
I intend to retrieve a (Int, Int) object from a function, but I don't know how to get the second element. I've tried the following commands so as to retrieve the second value, or convert it to a Seq or List, but with no luck.
scala> val s = (1,2)
s: (Int, Int) = (1,2)
scala> s(1)
<console>:9: error: (Int, Int) does not take parameters
s(1)
^
scala> val ss = List(s)
ss: List[(Int, Int)] = List((1,2))
scala> ss(0)
res10: (Int, Int) = (1,2)
Could anyone give me some idea? Thanks a lot!
val s = (1, 2)
is syntatic sugar and creates a Tuple2, or in other words is equivalent to new Tuple2(1, 2). You can access elements in tuples with
s._1 // => 1
s._2 // => 2
Likewise, (1, 2, 3) would create a Tuple3, which also has a method _3 to access the third element.

How can I find the index of the maximum value in a List in Scala?

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