I have to return the index of the first element in the list that contains the ’?’ character.
Why does it come up as -1 when it should be 8. Does indexOf not work on characters? Should I use indexWhere or will that have the same result?
scala> val lst = List("question?mark")
lst: List[String] = List(question?mark)
scala> lst.indexOf('?')
res2: Int = -1
When I make the val a string it works correctly
Try lst.indexWhere(_.contains("?"))
indexOf "Finds index of first occurrence of some value in this list." link
Therefore it finds string that equals "?" in the list.
.indexOf works on String
scala> "where is ?".indexOf('?')
res5: Int = 9
so try
lst(0).indexOf('?')
for each element of list you can use
scala> val lst = List("question?mark","where?","hello","why?")
lst: List[String] = List(question?mark, where?, hello, why?)
scala> lst.map(_.indexOf('?'))
res4: List[Int] = List(8, 5, -1, 3)
Related
I would like to duplicate even/odd elements in a list.
def even(number: Int): Boolean = {
if(number%2 == 0) true
else false
}
I tried something weird cause i have no idea how should I do that exactly.
scala> var x = List(1, 2, 3)
x: List[Int] = List(1, 2, 3)
scala> x.map(el => if(even(el)) el::x)
res143: List[Any] = List((), List(2, 1, 2, 3), ())
This is not what I expected. I'd like to return only one list with all elements where odd/even are duplicated.
Thanks for your help.
You can use flatMap to return a list per element, either containing just the element itself if the predicate doesn't match, or a list with the element duplicated if it does:
def even(n : Int) : Boolean = n%2 == 0
val l = List(1,2,3)
l.flatMap(n => if(even(n)) List(n,n) else List(n)) // -> List(1, 2, 2, 3)
You can filter the first collection for even numbers, and than concat with the original list:
scala> var l = List(1,2,3)
l: List[Int] = List(1, 2, 3)
scala> l.filter(_ % 2 == 0) ++ l
res14: List[Int] = List(2, 1, 2, 3)
If you want the List[Int] sorted, you can apply that after the concatenation:
scala> l.filter(_ % 2 == 0) ++ l sorted
res15: List[Int] = List(1, 2, 2, 3)
This saves you the allocation of a new List[Int] for every match of even. You filter only the elements you need, creating one List[Int], and then concatenating it with the original.
Since searching for :+ doesn't yield any results (thanks google!) I couldn't find any answer to my question:
Why is:
a :+ b
resulting in
List[Any]
if both 'a' and 'b' are of type
List[Int]
try it out yourself, following won't compile (Scala 2.11.6, Idea14):
object AAA extends App {
val a: List[Int] = List[Int]()
val b: List[Int] = List[Int]()
val x: List[Int] = a :+ b
}
thx in advance
:+ appends a single element to a List. So you are appending a List[Int] to a List[Int], resulting in something like (if a and b are both set to List(1, 2)):
List(1, 2, List(1, 2))
Scala calculates the most common type between the element type (Int) and the thing you append (List[Int]), which is Any.
You probably wanted to concatenate two lists:
val x: List[Int] = a ++ b
A : List[String]
B : List[String]
I want to know if any element of List B is a slice of any element of list A.
Whats the fastest way to check it?
I think the shortest way is: ListA.exists{ListB.contains}
Fastest for whom? For you or the CPU?
scala> val a = List("abc","def","ghi") ; val b = List("xy", "yz", "ef")
a: List[String] = List(abc, def, ghi)
b: List[String] = List(xy, yz, ef)
scala> b exists (s => a exists (_ contains s))
res0: Boolean = true
scala> val a = List("abc","def","ghi") ; val b = List("xy", "yz")
a: List[String] = List(abc, def, ghi)
b: List[String] = List(xy, yz)
scala> b exists (s => a exists (_ contains s))
res1: Boolean = false
I am looking for a nice way to remove first N elements which are equal from the ordered list, e.g.
List(1,1,1,2,3,3)
should return
removeSame(list) -> (1,1,1)
Is there a nice way to do it, rather than remove the head of the list and then use takeWhile on the remainder, and finally using dropwhile? I can think of simple non-functional solution but I was wondering whether any functional one also exists
The functional way to avoid the duplication of takeWhile and dropWhile to get a prefix and remainder is using span, i.e.
scala> val list = List(1,1,1,2,3,3)
list: List[Int] = List(1, 1, 1, 2, 3, 3)
scala> val (prefix, rest) = list span (_ == list.head)
prefix: List[Int] = List(1, 1, 1)
rest: List[Int] = List(2, 3, 3)
Is this what you look for?
scala> val l = List(1,1,1,2,3,3)
l: List[Int] = List(1, 1, 1, 2, 3, 3)
scala> l.takeWhile(_ == l.head)
res6: List[Int] = List(1, 1, 1)
scala> val l = List()
l: List[Nothing] = List()
scala> l.takeWhile(_ == l.head)
res7: List[Nothing] = List()
Not the best way of doing it, but this also works:
def removeSame(l: List) = if( !l.isEmpty) l.groupBy( x => x)(l.head) else List()
I'm new to scala and I'm trying to remove from a list of tuples elements which their first value is bigger than the second.
For example, From the list:
val list = List[(Int,Int)]((1,3),(3,1),(2,2))
I want to get the list:
val list = List[(Int,Int)]((1,3),(2,2))
So I used the following lines:
var newList = List[(Int, Int)]()
for (element <- list) {
if (element._1 <= element._2) {
newList ::= element;
}
}
But it feels very long for scala.. Is there a shorter way?
Like twillouer's and tzofia's solutions, but with pattern matching:
list filter { case (a, b) => a <= b }
You can simply do:
list.filter(element => element._1 <= element._2)
The filter function filters out elements which do not satisfy the given boolean condition.
you can use filter like this :
scala> val list = List[(Int,Int)]((1,3),(3,1),(2,2))
list: List[(Int, Int)] = List((1,3), (3,1), (2,2))
scala> val newList = list.filter(a => a._1 <= a._2)
newList: List[(Int, Int)] = List((1,3), (2,2))
or filterNot for the example :
scala> val newList = list.filterNot(a => a._1 > a._2)
newList: List[(Int, Int)] = List((1,3), (2,2))