Need to get the list from Option Vector - list

I have a vector of option of List of Tuple
like
val x = Vector(
Some(List(("x",2))),
Some(List(("x",2),("y",3))),
None,
Some(List(("x",2),("z",2))),
Some(List(("x",2),("z",2))),
None)
How to get the list from the above vector
Updated:
The final purpose is to get the total count of element in the list (we have three element only x or y or z).
like total count of x would return 8 and total count of y would return 3 and total count of z would return 4
like
val totalx = x.flatten.filter ....

x.flatMap {
case Some(l) => l.filter(_._1=="x").map(_._2)
case None => List(0)}.sum

Sorry i got the answer
x.flatten.flatten.filter(x => x._1 == "y").map(x => x._2).sum
used flatten to remove the none and then used flatten again to get all tuple flatten then filter and summing up

Related

Iterate through 2 lists at once Neo4j

I have two lists of numbers of the same length.
I want to go through both lists at once, multiply that pair of numbers and add them to an accumulator. In python I'd do:
a = [1,2,3]
b = [4,5,6]
acc = 0
for x,y in zip(a,b):
acc = acc + x*y
I've looked at foreachand list comprehension constructs in Neo4j but couldn't make it work... what should I do?
Here is an example using reduce and a range iterator based on the list size :
WITH [1,2,3] AS list1, [4,5,6] AS list2
RETURN reduce(
acc=0,
x IN range(0, size(list1)-1) |
acc + (list1[x] + list2[x])
) AS total

How to access an element of list within a list in scala

I want to access elements of a list within one list and check whether the elements are greater than a minimum value.
Example: List[([1,2],0.3), ([1.5,6],0.35), ([4,10],0.25), ([7,15],0.1)]
Let the minimum value: 1
The result should be: List[([1,6],0.65), ([4,10],0.25), ([7,15],0.1)]
As 1.5-1 is less than minimum value 1, it will merge the elements [1,2],0.3) and ([1.5,6],0.35) as [1, 6], 0.65, meaning it will take the 1st element of the inside list and last element of the 2nd element of the outside list and the 2nd element of the outside list will be added (0.3+0.35). This will be done for all elements of the outside list.
The code I tried is written below:
def reduce (d1:List[(Interval, Rational)]): List[(Interval, Rational)] =
{
var z = new ListBuffer[(Interval, Rational)]()
def recurse (list: List[(Interval, Rational)]): Unit = list match {
case List(x, y, _*) if ((y._1_1 - x._1_1) < min_val) =>
val i = x._1_1; y._1_2
val w = x._2 + y._2
z += (i,w)
else
z += x
recurse(list.tail)
case Nil =>
}
z.toList
}
But this is not working. Please help me to fix this.
OK, what you've written really isn't Scala code, and I had to make a few modifications just to get a compilable example, but see if this works for you.
type Interval = (Double,Double)
type Rational = Double
def reduce (lir:List[(Interval, Rational)]): List[(Interval, Rational)] = {
val minVal = 1.0
lir.foldLeft(List.empty[(Interval, Rational)]){
case (a, b) if a.isEmpty => List(b)
case (acc, ((i2a, i2b), r2)) =>
val ((i1a, _), r1) = acc.head
if (i2a - i1a < minVal) ((i1a, i2b), r1 + r2) :: acc.tail
else ((i2a, i2b), r2) :: acc
}.reverse
}
Test case:
reduce(List( ((1.0,2.0),0.3), ((1.5,6.0),0.35), ((4.0,10.0),0.25), ((7.0,15.0),0.1) ))
// result: List[(Interval, Rational)] = List(((1.0,6.0),0.6499999999999999), ((4.0,10.0),0.25), ((7.0,15.0),0.1))

Finding index of row from a list

I am trying to get the index of a row using Scala from a list consisting of lists of integers List[List[Int]]. I already have two functions that given the row index/column index and the grid as parameters, it outputs all the elements in that row. What I need is a function that given a particular element (eg: 0), it finds its row index and column index and puts them in a list: List[(Int, Int)]. I tried to code a function that gives back an index when encountering 0 and then I passed the function to the whole grid. I don't know if I'm doing it the right way. Also, I couldn't figure out how to return the list.
Also, I cannot use any loops.
Thanks in advance.
def Possibilities(): List[Int] = {
def getRowIndex(elem: Int): Int = elem match
{
case 0 => sudoku.grid.indexOf(sudoku.row(elem))
case x => x
}
val result1 = sudoku.grid map {row => row map getRowIndex}
}
I think with two dimensions it is much easier to write such a method with for comprehensions.
Given a List[List[Int]] like this:
val grid = List(
List(1, 2, 3),
List(4, 5, 6),
List(3, 2, 1))
we can simply walk through all the rows and columns, and check whether each element is the one we are looking for:
def possibilities(findElem: Int): List[(Int, Int)] = {
for (
(row, rowIndex) <- grid.zipWithIndex;
(elem, colIndex) <- row.zipWithIndex
if elem == findElem
) yield (rowIndex, colIndex)
}
The yield keyword creates a collection of the results of the for loop. You can find more details on Scala's forloop syntax here (and a more thorough discussion on how this relates to map, flatMap, etc. here).
So, if you don't want to use a for loop, simply 'translate' it into an equivalent expression using map. flatMap, and withFilter:
def possibilities(findElem: Int): List[(Int, Int)] = {
grid.zipWithIndex flatMap { rowAndIndex =>
rowAndIndex._1.zipWithIndex.withFilter(_._1 == findElem) map { colAndIndex =>
(rowAndIndex._2, colAndIndex._2)
}
}
}
Step 1, create a collection of all possible tuples of indices, with a for comprehension (for looks like a loop but it is not)
val tuples = for (i <- grid.indices; j <- grid.head.indices) yield (i, j)
Step 2, filter this collection
tuples.filter { case (i, j) => grid(i)(j) == valueToFind }

Scala conditional sum of elements in a filtered tuples list

I'm new to Scala and need a little help about how to combine
filters and sum on a list of tuples.
What I need is the sum of integers of a filtered tuples list which
essentially the answer to the question:
What is the sum of all set weights?
The result should be 20 for the sample list below
The list is pretty simple:
val ln = List( ("durationWeight" , true, 10),
("seasonWeight" , true, 10),
("regionWeight" , false, 5),
("otherWeight" , false, 5)
Filtering the list according to the Boolean flag is a simple:
val filtered = ln.filter { case(name, check, value) => check == true }
which returns me the wanted tuples. Getting the sum of all them seems to work
with a map followed by sum:
val b = filtered.map{case((name, check, value) ) => value}.sum
Which returns me the wanted sum of all set weights.
However, how do I do all that in one step combining filter, map and sum,
ideally in an elegant one liner?
Thanks for your help.
ln.collect{ case (_, true, value) => value }.sum
Another approach for the heck of it:
(0 /: ln)((sum,x) => if (x._2) sum + x._3 else sum)

Scala insert into list at specific locations

This is the problem that I did solve, however being a total imperative Scala noob, I feel I found something totally not elegant. Any ideas of improvement appreciated.
val l1 = 4 :: 1 :: 2 :: 3 :: 4 :: Nil // original list
val insert = List(88,99) // list I want to insert on certain places
// method that finds all indexes of a particular element in a particular list
def indexesOf(element:Any, inList:List[Any]) = {
var indexes = List[Int]()
for(i <- 0 until inList.length) {
if(inList(i) == element) indexes = indexes :+ i
}
indexes
}
var indexes = indexesOf(4, l1) // get indexes where 4 appears in the original list
println(indexes)
var result = List[Any]()
// iterate through indexes and insert in front
for(i <- 0 until indexes.length) {
var prev = if(i == 0) 0 else indexes(i-1)
result = result ::: l1.slice(prev, indexes(i)) ::: insert
}
result = result ::: l1.drop(indexes.last) // append the last bit from original list
println(result)
I was thinking more elegant solution would be achievable with something like this, but that's just pure speculation.
var final:List[Any] = (0 /: indexes) {(final, i) => final ::: ins ::: l1.slice(i, indexes(i))
def insert[A](xs: List[A], extra: List[A])(p: A => Boolean) = {
xs.map(x => if (p(x)) extra ::: List(x) else List(x)).flatten
}
scala> insert(List(4,1,2,3,4),List(88,99)){_ == 4}
res3: List[Int] = List(88, 99, 4, 1, 2, 3, 88, 99, 4)
Edit: explanation added.
Our goal here is to insert a list (called extra) in front of selected elements in another list (here called xs--commonly used for lists, as if one thing is x then lots of them must be the plural xs). We want this to work on any type of list we might have, so we annotate it with the generic type [A].
Which elements are candidates for insertion? When writing the function, we don't know, so we provide a function that says true or false for each element (p: A => Boolean).
Now, for each element in the list x, we check--should we make the insertion (i.e. is p(x) true)? If yes, we just build it: extra ::: List(x) is just the elements of extra followed by the single item x. (It might be better to write this as extra :+ x--add the single item at the end.) If no, we have only the single item, but we make it List(x) instead of just x because we want everything to have the same type. So now, if we have something like
4 1 2 3 4
and our condition is that we insert 5 6 before 4, we generate
List(5 6 4) List(1) List(2) List(3) List(5 6 4)
This is exactly what we want, except we have a list of lists. To get rid of the inner lists and flatten everything into a single list, we just call flatten.
The flatten trick is cute, I wouldn't have thought of using map here myself. From my perspective this problem is a typical application for a fold, as you want go through the list and "collect" something (the result list). As we don't want our result list backwards, foldRight (a.k.a. :\) is here the right version:
def insert[A](xs: List[A], extra: List[A])(p: A => Boolean) =
xs.foldRight(List[A]())((x,xs) => if (p(x)) extra ::: (x :: xs) else x :: xs)
Here's another possibility, using Seq#patch to handle the actual inserts. You need to foldRight so that later indices are handled first (inserts modify the indices of all elements after the insert, so it would be tricky otherwise).
def insert[A](xs: Seq[A], ys: Seq[A])(pred: A => Boolean) = {
val positions = xs.zipWithIndex filter(x => pred(x._1)) map(_._2)
positions.foldRight(xs) { (pos, xs) => xs patch (pos, ys, 0) }
}