None of the following candidate is applicable because of receiver type mismatch in `HashMap.getOrDefault()` function - dictionary

According to the official Oracle documentation, the HashMap.getOrDefault(Object Key, V defaultValue) function can take two arguments, but the compiler reported an error when I run the following program.
fun main(args: Array<String>) {
val numbersMap = mapOf(
"one" to 1,
"two" to 2,
"three" to 3,
"four" to 4,
"five" to 5
)
println(numbersMap.get("one"))
println(numbersMap["one"])
println(numbersMap.getOrDefault("four", 10))
println(numbersMap["five"])
}
C:\Users\forestfh\Documents\KotlinProjects>kotlinc GetOrDefault.kt
GetOrDefault.kt:11:24: error: unresolved reference. None of the following candid
ates is applicable because of receiver type mismatch:
public inline fun <R, T : String> Result<String>.getOrDefault(defaultValue: Stri
ng): String defined in kotlin
println(numbersMap.getOrDefault("four", 10))

You can use getOrElse() extension function to retrieve either a stored value or default value:
println(numbersMap.getOrElse("four") { 10 })

Related

RxJava - Count events on the fly

I would like to count objects passing from observable. I know there is a count operator but that can't be used for infinite streams because it waits for completition.
What I want is something like Value -> operator -> Pair(Int, Value). I know there could be a problem with int (or long) overflow and that is maybe a reason nothing like this exists but I still have feeling I've seen something like this before. One can implement this with scan operator but I thought there is a simpler way.
Output would be like:
Observable.just(Event1, Event2, Event3) -> (1, Event1), (2, Event2), (3, Event3)
You can solve your problem using the RxJava Scan method:
Observable.just("a", "b", "c")
.scan(new Pair<>(0, ""), (pair, s) -> new Pair<>(pair.first + 1, s))
.skip(1)
Pair<>(0, "") is your seed value
Lambda (pair, s) -> new Pair<>(pair.first + 1, s) takes the seed value and value emitted by original observable and then produces the next Pair value to be emitted and fed back into the lambda
Skip(1) is needed to avoid emitting the seed value
Count means a state change. So you can use a "stateful" map instead of an anonymous class.
ex:
class Mapper<T, R>(val mapper: (T) -> R) : Function<T, Pair<Int, R>> {
private var counter = 0
override fun apply(t: T): Pair<Int, R> {
return Pair(counter++, mapper(t))
//or ++counter if you want start from 1 instead of zero
}
}
//usage
val mapper = Mapper<String, String> { it.toUpperCase() }
Observable.just("a", "b", "c")
.map(mapper)
.subscribe {
Log.d("test logger", it.toString())
}

How to prototype (initiate) S4 slots derived from other slots?

Suppose I have an S4 class
setClass("Person", representation(name = "character", first_letter = "character")
and I want to autofill the slot first_letter when an object is initiated. Something like
> jack <- new("Person", name = "Jack")
> print(jack)
# Slot "name":
# "Jack"
#
# Slot "first_letter":
# "J"
I think I should do something like this:
setClass("Person",
representation(name = "character", first_letter = "character"),
prototype(first_letter = substring(self#name, 1, 1))
)
Of course, I could write a method to do this in a separate statement. I'm specifically interested in the case where the first_letter slot is initiated with information from another slot upon calling new.
Any help is greatly appreciated!
One way is to see the first_letter as a private field.
Create a custom constructor ( initiate) that set the private fields using other public fields
Define set/get for public slots to keep the same logic when you change of of the other field.
Here one implementation:
## Note the use of `.` for private field
## this is just a convention
Person <- setClass("Person", representation(Name = "character",
first_letter. = "character"))
## define setter and getter for public slots
setGeneric("Name", function(x) standardGeneric("Name"))
setMethod("Name","Person",function(x) x#Name)
setGeneric("Name<-", function(x,value) standardGeneric("Name<-"))
setMethod("Name<-","Person",function(x,value){
x#Name <- value
x#first_letter. <- substring(value, 1, 1)
x
})
## define the constructor
## Note that we don't give an argument to the ctor
## to init the private field
setMethod ("initialize", signature = "Person",
definition = function (.Object,
name) {
.Object#Name <- name
.Object#first_letter. <- substring(name, 1, 1)
return (.Object)
})
Now , testing this by creating an object:
> p <- Person(name="Amine")
> p
An object of class "Person"
Slot "Name":
[1] "Amine"
## the slot is automatically initialized
Slot "first_letter.":
[1] "A"
Then is we change the slot value:
> Name(p) <- "Xvalue"
> p
An object of class "Person"
Slot "Name":
[1] "Xvalue"
## Again the private slot is updated
Slot "first_letter.":
[1] "X"
The prototype parameter would let you to give default values to your object slots.
But as you are intending to do some kind of preprocessing of the data before assigning them to the slots in your object,
you will need to define an
initialization method for your class.
Also you may want to use the slot parameter...
representation works the same,
but it is intended for S3 inheritance which I am not sure is what you intend (check ?setClass)
Then define your class
setClass ("Person", slots = c (name = "character", first_letter = "character"))
or
setClass("Person", representation (name = "character", first_letter = "character"))
and the initialization method:
setMethod ("initialize", signature = "Person",
definition = function (.Object,
name,
first_letter = substring (name, 1, 1)) {
.Object#name <- name
.Object#first_letter <- first_letter
return (.Object)
})
Note: the .Object needs to be called like this (same name defined in the generic method).
Also usually you have to remember to return it...
Now you should be able to initialize as you want
new("Person", name = "Jack")

Append a value in an Array nested in a Dictionary in Swift

I have a strange issue with the following code :
var dict = ["KEY" : [1, 2]]
println(dict["KEY"]) // Output is "Optional([1, 2])"
println(dict["KEY"]!) // Output is "[1, 2]"
dict["KEY"]!.append(3) // Error : '(String, Array<Int>)' does not have a member named 'append'
dict["KEY"]! += 3 // Error : type 'DictionaryIndex<String, Array<Int>>' does not conform to protocol 'StringLiteralConvertible'
My goal is to transform the dict variable from ["KEY" : [1, 2]] to ["KEY" : [1, 2, 3]].
I have probably missed something but I don't see what.
Firstly, from apple docs:
Conversely, if you assign an array or a dictionary to a constant, that
array or dictionary is immutable, and its size and contents cannot be
changed.
I think if you assign an array as a value of key within dictionary it goes the same way.
In addition Swift collections are copied whenever they are assigned or passed as a parameter.
If you really want to change array in dict, I guess you may create new array with appended items for example and reassign the value of dict
var arrayInit = [1, 2]
var dict = ["KEY" : arrayInit]
//somewhere
var array = dict["KEY"]!
array.append(3)
dict["KEY"] = array;
println(dict["KEY"]!) // Output is "[1, 2]"
That will do it...
import Cocoa
import Foundation
var dict = ["KEY" : [1, 2]]
println(dict["KEY"]) // Output is "Optional([1, 2])"
println(dict["KEY"]!) // Output is "[1, 2]"
var array = dict["KEY"]!
array.append(3)
array += 3
dict["KEY"] = array

S4 method with a scalar(non vector) return value

I want to define an S4 method that return a scalar return value. Here I mean by scalar value , the contrary of a vector.
setGeneric("getScalar", function(value, ...)
standardGeneric("getScalar")
)
setMethod("getScalar",
signature(value = "ANY"),
def = function(value, ...) getScalar(value,...), ## call external function
valueClass = "atomic" ### atomic is false, what should I do ?
)
I can't override the method by its output , I mean I can't define many function having the same signature with a different return valueClass :numeric , integer , character ,..
So How can I do this?
EDIT to give more context :
I think is atomic is confusing here. I mean by scalar a numeric value or a boolean or a character, of length one. To give more context I will have 3 functions in my package:
dbGetQuery :return a list/data.frame : i.e some table rows
dbGetScalar :return a scalar value : i.e count(*),table_name,..
dbGetNoQuery :return nothing : update/insert actions
It is an extension to DBI interface.
EDIT2
We can assume that scalar is a vector of length 1. But I can't express this condition using S4. in c# or c, I would write
double[] // vector
double // scalar
Maybe I should just change the name of my function.
One possibility is to check the value of the return type after method dispatch
setGeneric("getScalar", function(x, ...) {
value <- standardGeneric("getScalar")
if (!is.atomic(value) || length(value) != 1L)
stop("not a scalar atomic vector")
value
})
setMethod(getScalar, "ANY", function(x, ...) x)
Another possibility is to define a 'Scalar' class, with a validity check on the base class that enforces the constraint
.Scalar <- setClass("Scalar", contains="ANY", validity=function(object) {
if (length(object) != 1L)
"non-scalar object"
else TRUE
}, prototype=NA)
or controlling scalar types more strongly with a small hierarchy based on a virtual class
setClass("Scalar", validity=function(object) {
if (length(object) != 1L)
"non-scalar object"
else TRUE
})
.ScalarInteger <- setClass("ScalarInteger",
contains=c("Scalar", "integer"),
prototype=prototype(NA_integer_))
This is the approach taken in Bioconductor's Biobase package, with a mkScalar constructor.

Getting object instance by string name in scala

I need the object (or "singleton object" or "companion object"... anything but the class) defined by a string name. In other words, if I have:
package myPackage
object myObject
...then is there anything like this:
GetSingletonObjectByName("myPackage.myObject") match {
case instance: myPackage.myObject => "instance is what I wanted"
}
In scala 2.10 we can do like this
import scala.reflect.runtime.universe
val runtimeMirror = universe.runtimeMirror(getClass.getClassLoader)
val module = runtimeMirror.staticModule("package.ObjectName")
val obj = runtimeMirror.reflectModule(module)
println(obj.instance)
Scala is still missing a reflection API. You can get the an instance of the companion object by loading the companion object class:
import scala.reflect._
def companion[T](implicit man: Manifest[T]) : T =
man.erasure.getField("MODULE$").get(man.erasure).asInstanceOf[T]
scala> companion[List$].make(3, "s")
res0: List[Any] = List(s, s, s)
To get the untyped companion object you can use the class directly:
import scala.reflect.Manifest
def companionObj[T](implicit man: Manifest[T]) = {
val c = Class.forName(man.erasure.getName + "$")
c.getField("MODULE$").get(c)
}
scala> companionObj[List[Int]].asInstanceOf[List$].make(3, "s")
res0: List[Any] = List(s, s, s)
This depends on the way scala is mapped to java classes.
Adjustment to Thomas Jung's answer above: you would do better to say companion[List.type] because a) this should be a stable way to refer to it, not dependant on the name mangling scheme and b) you get the unerased types.
def singleton[T](implicit man: reflect.Manifest[T]) = {
val name = man.erasure.getName()
assert(name endsWith "$", "Not an object: " + name)
val clazz = java.lang.Class.forName(name)
clazz.getField("MODULE$").get(clazz).asInstanceOf[T]
}
scala> singleton[List.type].make(3, "a")
res0: List[java.lang.String] = List(a, a, a)
Barring reflection tricks, you can't. Note, for instance, how the method companion is defined on Scala 2.8 collections -- it is there so an instance of a class can get the companion object, which is otherwise not possible.
Scala 2:
val runtimeMirror = universe.runtimeMirror(this.getClass.getClassLoader)
val objectClass = Class.forName("org.test.MyObject$")
val moduleSymbol = runtimeMirror.staticModule(objectClass.getName)
val moduleMirror = runtimeMirror.reflectModule(moduleSymbol)
val instance = moduleMirror.instance
Or just use Java API to get the value from the static field:
val instance = objectClass.getField("MODULE$").get(null)
Mind the $ in the object name.

Resources