In this code I can able to understand the use of X for dynamic type casting. But I can't able to understand how add function really loads the data.
anyone please help me to understand step by step execution of add and printNodes method in detail. Thanks
class UsingGenericsForLinkedList[X] {
private class Node[X](elem: X) {
var next: Node[X] = _
override def toString = elem.toString
}
private var head: Node[X] = _
def add(elem: X) { //Add element in the linekd list
val value = new Node(elem)
value.next = head
head = value
}
private def printNodes(value: Node[X]) { // prining value of the nodes
if (value != null) {
println(value)
printNodes(value.next)
}
}
def printAll() { printNodes(head) } //print all the node values at a time
}
In a (singly) linked list, one maintains cells (here the Node class) that carry an element payload and a pointer to the next cell. Here you have a mutable linked list, so the next pointers can be updated (are mutable vars). The outer structure keeps a pointer to head, the first node of the list, which is initially null to indicate an empty list. When you traverse, you find the first node in head, then do something with its payload (the payload is elem in Node which is only made available here through toString), then repeat the procedure by looking at the next pointer, until that becomes null.
Note that add replaces head, and puts the previous value of head into the next field of the newly inserted node. So technically, this prepends an element to the list, it will become the first element to be found. So if you do add(1), add(2), add(3), you get the traversal 3, 2, 1. This is equivalent to :: in Scala's default List class.
Here is a tutorial on Scala's (immutable) List type; the only difference there is that you never replace next or head pointers, but return a new head cell when you prepend.
Related
I have a recursive function which collects the leaf nodes of a kd-tree. This function has to take KdNode as an argument. The KdNode has the following class definition:
case class KdNode(value: (Double, Double), left: Option[KdNode], right: Option[KdNode], axis: Int, BB_A:BoundingBox, BB_B:BoundingBox)
The function definition where it is taken as an argument is:
def collectLeafNodes(t:KdNode): List[BoundingBox] = {
if(t == None) return
if (t.left == None && t.right == None) {
Some(listBoundingBox.::(t.BB_A,t.BB_B))
return
}
collectLeafNodes(t.left)
collectLeafNodes(t.right)}
Here, I encounter error on the last 2 lines saying: "Type mismatch, expected: KdNode, actual: Option[KdNode].
I am calling this function by building the kd-tree in variable "tree" and giving it as an argument:
val listofBoundingBoxes=collectLeafNodes(tree)
What is a possible workaround in this situation? In addition, I think there should be a way to pass the root node instead of tree to the collectLeafNodes function, is that possible given the tree is built in a separate function.
Thanks.
You ask, in the comments, how it can be done without return. Here's one way.
def collectLeafNodes(t :KdNode) :List[BoundingBox] =
List(t.BB_A, t.BB_B) :::
t.left.fold(List.empty[BoundingBox])(collectLeafNodes) :::
t.right.fold(List.empty[BoundingBox])(collectLeafNodes)
The result, without return, is the concatenation of 3 lists:
Since t is a KdNode and not an Option[KdNode], we know that the the BB values are real. That's the 1st List.
If t.left is None then the 2nd List is empty, otherwise the 2nd List is whatever the recursive call to collectLeafNodes(t.left) returns. (The argument is automatically supplied so it need not be specified.)
Same for the 3rd List with t.right
corrected for leaf nodes only
def collectLeafNodes(t :KdNode) :List[BoundingBox] = {
if (t.left.isEmpty && t.right.isEmpty) List(t.BB_A, t.BB_B)
else t.left .fold(List.empty[BoundingBox])(collectLeafNodes) :::
t.right.fold(List.empty[BoundingBox])(collectLeafNodes)
}
You can map over the option object:
val res: List[BoundingBox] = t.left.map(collectLeafNodes).getOrElse(List())
Because t.right is type of Option and not type of Kdnode.
You can unwrap Option to solve this e.g.
collectLeafNodes(t.right.get)}
collectLeafNodes(t.right.orElse(None)}
Hope this helps
With a background from object-oriented programming I am not able to understand how to make immutable lists in Scala.
Example; I want to make a list of 10 random people:
object MyApplication extends App {
val numberOfPersons = 10 : Int
val listOfPersons = makeListOfPersons(numberOfPersons) : List[Person]
def makeListOfPersons( numberOfPersons : Int ) : List[Person] = {
// TODO: return a immutable list of 10 persons
}
}
class Person {
/**
Generic content,
like age and name.
* */
}
What is the "correct" way of making an immutable list in Scala?
If you know what collection type you want, you may be able to use the tabulate method on that type:
List.tabulate(10)(makePerson)
In this case makePerson is a function that takes an Int and returns the Person object for that Int.
If you don't care about the collection type, you can call map on the range 1 to 10 like this:
(1 to 10).map(makePerson)
If you don't need to use the Int parameter, you can do this:
List.tabulate(10)(_ => makeRandomPerson())
In this particular case,
List.fill(numberOfPersons){ codeThatCreatesASinglePerson }
seems most appropriate.
In most other cases: Nil creates an empty list, x :: y prepends an element x to list y.
If you want to append to list, instead of prepending to it, then you can take a collection.mutable.ListBuffer, append to it all the elements that you want to have in the list, and then call toList when you're done... or just use the built-in factory methods that do exactly that.
As the default List in Scala is immutable, the right way to add an element is to return a new list with the new element plus the older elements.
As a matter of fact, List has two methods, among others:
+:
++
The first one takes an element, add it as the first element and the rest of the list as it's tail and then returns the resulting list.
The other one takes another "collection" as parameter and adds it to the first list at the start.
List has another methods for adding the new element as the last one.
In Scala, these operations are permitted but take into consideration that always a new instance will be retrieved with the requested modifications as all objects are immutable by default.
As for your code goes, you could try with something like this:
object MyApplication extends App {
val numberOfPersons: Int = 10
val listOfPersons: List[Person] = makeListOfPersons(numberOfPersons)
def makeListOfPersons( numberOfPersons : Int ) : List[Person] = {
(1 to numberOfPersons).foldLeft(List.empty[Person]){ (accum, elem) =>
new Person() :: accum
}
}
}
(1 to numberOfPersons) creates a range, which could be seen as a List of ints, which will be traversed by foldLeft. This method will iterate through that list, and receives a seed, in this case an empty list of Person. Then, for every element in the int's list, a new Person is created and add to the list, returned as is the last expression and used the accumulator for the next iteration. Finally, a list of ten instances of Person is retrieved.
There are 5 ways to create List in scala:
Lisp style:
val list = 1::2::3::Nil
this style can also be thought of as a Haskell or functional programming (FP) style.
Java Style:
val list = List(1,2,3)
Scala List with range method
List.range(1, 10)
Create scala List with fill
List.fill(3)(5)
Scala List with tabulate
List.tabulate(5)(n => n * n)
element of the list are created according to the function we supply.
for more info please read this :
Preferred way to create a Scala list
How do you get and remove an arbitrary element from a mutable HashSet in Scala (similar to python set pop method)? Also what would be the performance of the api?
For extracting and removing elements in undefined order from a mutable hash set, try a combination of head and -= (remove):
import scala.collection.mutable.HashSet
def pop[A](hs: HashSet[A]): A = {
val a = hs.head
hs -= a
a
}
val example = HashSet.empty[Int] ++ (0 to 9)
while (!example.isEmpty) {
val p = pop(example)
println("Pop element: " + p)
}
I'm not sure whether it's caching any keys or hashes internally, but afaik it's either just O(1) or amortized O(1).
#Andrey's answer above should suffice to answer your question as he said
you can use .head function to pop an element.
Here are some more details.
Sets are one of the collection libraries of Scala which provide both mutable and immutable methods. If you want specific element to be removed from Sets then there is - and + methods. - method is used for removing an element from a Set and a new Set is returned. Similarly + method is used for adding an element in a Set which also returns a new Set with the element added. So you can write pop and set functions that will remove and add specific elements.
def popFromSet[T](set: Set[T], stringToPop: T) = {
set - stringToPop
}
def setToSet[T](set: Set[T], stringToPop: T) = {
set + stringToPop
}
And you can use them as
popFromSet(stringSet, "second")
setToSet(popFromSet(stringSet, "second"), "second2")
popFromSet(intSet, 2)
....
List way
You can do the above Set to List
If you have a HashSet as
Set("first", "second", "third")
You can get the second element popped out by doing
val hashList = hashSet.toList
hashList(hashList.indexOf("second"))
and if you want to remove the second element from the HashSet then
hashSet - hashList(hashList.indexOf("second"))
I hope the answer is helpful
I am trying to build a wrapper around data saved in a redis database.
What I want to do is access it as normal as possible as if I have a scala value of some type.
It works, except for comparing it to anything (with == or similar).
So I want to be able to compare it to objects of the inner type.
Best I'll give example code first. This is a rough abstraction of my wrapper:
case class RedisObjectValue[T](name: String, default: T) {
def :=(value: T): Boolean = {
redisMagic.set(name, value)
}
def get: T = {
redisMagic.get[T](name).getOrElse(default)
}
override def equals(o: Any) = o match {
case ov: RedisObjectValue[T] =>
if (this.hashCode() == ov.hashCode()) true // Same reference
else this.get == ov.get
case v =>
// If we don't compare to another RedisObjectValue, let the equals method of data type handle it
this.get.equals(v)
}
}
I have an implicit conversion set up in the companion object so that I can use the wrapper wherever I would use the base type.
object RedisObjectValue {
implicit def objectValueToValue[T](ov: RedisObjectValue[T]): T = {
ov.get
}
}
So, as I said, everything works.
Except the comparing stuff. For that, let's say I have a class Player two values, userId and name.
class Player {
val userId = RedisObjectValue("userId", 0)
val name = RedisObjectValue("player", "Unknown")
}
And now I have a list of players and want to filter to get all players with name "Unknown".
list.filter(_.name == "Unknown")
Which does not work. If I extend the filter filter call and write a function, it tells me in IntelliJ "Comparing unrelated types".
And yeah, I understand what it is telling me, but I want to solve that. I mean I can easily compare Long to Int and similar stuff, so there must be a way to make them comparable, right?
In the code above I have even written the equals function which uses the comparison to the inner type, but it seems like it is not used.
Of course, I can always call .get on the values, like players.filter(_.name.get == "Unknown"), but that's a bit dirty and I would love to avoid that.
EDIT: Found the real problem after some analysis
Old text still above for reading, I will explain the problem here now.
I have a snippet which shows what is not working: https://ideone.com/AmQrkH
The Problem: The RedisObjectValue is defined as Long. When I am comparing it now with
players.filter(_.userId == 2)
for example, it doesn't give any results, even if there are players with userId 2, or to be more exact: 2l.
For direct Long it's not a problem.
players.filter(_._id == 2)
is working.
So is there any fix for that, so that comparable instances of classes to T can also be compared to RedisObjectValue[T], and not just T itself?
Replace this.get.equals(v) with get == v. (Removing this is unrelated, just a good idea in general, the main thing is to use == instead of equals).
Consider this:
scala> 2 equals 2L
res79: Boolean = false
scala> 2 == 2L
res80: Boolean = true
I have a var permutedTables = HashMap[List[Int], List[String, String]] defined globally. I first populate the Hashmap with the keys in a method, which works.
print(permutedTables) :
Map(List(1,2,3,4) -> List(),
List(2,4,5,6) -> List(), etc...)
The problem occurs when I want to update the values (empty lists) of the HashMap inside a for loop (inside a second method). In other words, I want to add tuples (String, String) in the List() for each key.
for(pi_k <- permutedTables.keySet){
var mask = emptyMask;
mask = pi_k.foldLeft(mask)((s, i) => s.updated(i, '1'))
val maskB = Integer.parseInt(mask,2)
val permutedFP = (intFP & maskB).toBinaryString
// attempt 1 :
// permutedTables(pi_k) :+ (url, permutedFP)
// attempt 2 :
// permutedTables.update(pi_k, permutedTables(pi_k):::List((url, permutedFP)))
}
The values do not update. I still have empty lists as values. I don't understand what is wrong with my code.
EDIT 1: When I call print(permutedTables) after any of the two attempts (inside the loop), the value seem updated, but when I call it outside of the loop, the Lists are empty
EDIT 2: The second attempt in my code seems to work now(!). But why does first not work ?
The second attempt in my code seems to work now(!). But why does first not work ?
Because what you do in the first case is get a list from permutedTables, add an element and throw away the result without storing it back. It would work if you mutated the value, but a List is immutable. With List, you need
permutedTables += pi_k -> permutedTables(pi_k) :+ (url, permutedFP)
Or, as you saw, update.
You can use e.g. ArrayBuffer or ListBuffer as your value type instead (note that you need :+= instead of :+ to mutate them), and convert to your desired type at the end. This is going to be rather more efficient than appending to the end of the list, unless the lists are quite small!
Finally, note that you generally want either var or a mutable type, not both at the same time.