Lazy evaluation in a Map
I'm trying to make a function that executes other functions (which return Strings
) depending on an input.
For example:
def execute(input: String) = {
val actions = Map("foo" -> someObject.doStuff(), "bar" -> someObject.doThing())
actions.get(input) }
Is there a way to make the functions in the Map
to be called only if the corresponding key exists?
scala
add a comment |
I'm trying to make a function that executes other functions (which return Strings
) depending on an input.
For example:
def execute(input: String) = {
val actions = Map("foo" -> someObject.doStuff(), "bar" -> someObject.doThing())
actions.get(input) }
Is there a way to make the functions in the Map
to be called only if the corresponding key exists?
scala
what is the default function you want to call if key is doesn't exist?
– Raman Mishra
Nov 17 '18 at 18:44
Then None should be returned.
– Kah
Nov 17 '18 at 18:53
You can start with something like:if (actions isDefinedAt input) actions.get(input) else None
. Better yet, try to usescala.util.Try
!
– jrook
Nov 17 '18 at 19:55
I think the only way to do this is to convert the values to a thunk.
– erip
Nov 17 '18 at 20:42
2
@jrookMap#get
already returns anOption[T]
-- no need to checkisDefinedAt
.
– erip
Nov 18 '18 at 2:52
add a comment |
I'm trying to make a function that executes other functions (which return Strings
) depending on an input.
For example:
def execute(input: String) = {
val actions = Map("foo" -> someObject.doStuff(), "bar" -> someObject.doThing())
actions.get(input) }
Is there a way to make the functions in the Map
to be called only if the corresponding key exists?
scala
I'm trying to make a function that executes other functions (which return Strings
) depending on an input.
For example:
def execute(input: String) = {
val actions = Map("foo" -> someObject.doStuff(), "bar" -> someObject.doThing())
actions.get(input) }
Is there a way to make the functions in the Map
to be called only if the corresponding key exists?
scala
scala
edited Nov 17 '18 at 19:13
Kah
asked Nov 17 '18 at 18:31
KahKah
214
214
what is the default function you want to call if key is doesn't exist?
– Raman Mishra
Nov 17 '18 at 18:44
Then None should be returned.
– Kah
Nov 17 '18 at 18:53
You can start with something like:if (actions isDefinedAt input) actions.get(input) else None
. Better yet, try to usescala.util.Try
!
– jrook
Nov 17 '18 at 19:55
I think the only way to do this is to convert the values to a thunk.
– erip
Nov 17 '18 at 20:42
2
@jrookMap#get
already returns anOption[T]
-- no need to checkisDefinedAt
.
– erip
Nov 18 '18 at 2:52
add a comment |
what is the default function you want to call if key is doesn't exist?
– Raman Mishra
Nov 17 '18 at 18:44
Then None should be returned.
– Kah
Nov 17 '18 at 18:53
You can start with something like:if (actions isDefinedAt input) actions.get(input) else None
. Better yet, try to usescala.util.Try
!
– jrook
Nov 17 '18 at 19:55
I think the only way to do this is to convert the values to a thunk.
– erip
Nov 17 '18 at 20:42
2
@jrookMap#get
already returns anOption[T]
-- no need to checkisDefinedAt
.
– erip
Nov 18 '18 at 2:52
what is the default function you want to call if key is doesn't exist?
– Raman Mishra
Nov 17 '18 at 18:44
what is the default function you want to call if key is doesn't exist?
– Raman Mishra
Nov 17 '18 at 18:44
Then None should be returned.
– Kah
Nov 17 '18 at 18:53
Then None should be returned.
– Kah
Nov 17 '18 at 18:53
You can start with something like:
if (actions isDefinedAt input) actions.get(input) else None
. Better yet, try to use scala.util.Try
!– jrook
Nov 17 '18 at 19:55
You can start with something like:
if (actions isDefinedAt input) actions.get(input) else None
. Better yet, try to use scala.util.Try
!– jrook
Nov 17 '18 at 19:55
I think the only way to do this is to convert the values to a thunk.
– erip
Nov 17 '18 at 20:42
I think the only way to do this is to convert the values to a thunk.
– erip
Nov 17 '18 at 20:42
2
2
@jrook
Map#get
already returns an Option[T]
-- no need to check isDefinedAt
.– erip
Nov 18 '18 at 2:52
@jrook
Map#get
already returns an Option[T]
-- no need to check isDefinedAt
.– erip
Nov 18 '18 at 2:52
add a comment |
3 Answers
3
active
oldest
votes
object someObject {
def doStuff() = "foo"
def doThing() = "bar"
}
//if you need a string as a return value.
//there will be empty string for missing keys
def execute(input: String):String = {
val actions = Map( "foo" -> someObject.doStuff _ ,
"bar" -> someObject.doThing _ )
actions.getOrElse(input,()=>"")()
}
//if you need an Option[String] as a return value.
//there will be None value for missing keys
def executeOption(input: String):Option[String] = {
val actions = Map( "foo" -> someObject.doStuff _ ,
"bar" -> someObject.doThing _ )
actions.get(input).map(_())
}
Thanks, your executeOption was exactly what I was looking for. I was also wondering how to implement this when some of the functions in someObject take parameters?
– Kah
Nov 18 '18 at 14:14
this is quite complicated using pure scala. the problem is that in scala we can transform method into function literal using eta notation likesomeObject.doStuff _
, but function literals with parameters are not supported out of the box. There is a FunctionN type class in cats library that allows doing something like that using macros, but I'm not a very good at this staff.
– Bogdan Vakulenko
Nov 18 '18 at 14:22
add a comment |
From what I can tell, you are not really looking for lazy map
. You are trying to build some kind of execution engine, which does something based on string input.
Now, the simple trick to achieve this is to have a actual functions
in your Map
and execute the corresponding function for the input string.
So, lets say you have an object A,
object A {
var i = 1
def doFirstThing(): Unit = {
i = i + 1
println(s"first thing :: $i")
}
def doSecondThing(): Unit = {
i = i - 1
println(s"second thing :: $i")
}
}
And you want to build an executor for executing doFirstThing
for input "first"
and doSecondThing
for input "second"
.
So, now you need to create functions
f1
and f2
which will execute A.doFirstThing()
and A.doSecondThing()
.
Its pretty simple actually,
scala> val f1 = () => A.doFirstThing()
// f1: () => Unit = $$Lambda$1235/1187572055@7e192338
scala> val f2 = () => A.doSecondThing()
// f2: () => Unit = $$Lambda$1236/1696761182@47df3efe
Or, you can use _
to convert def
(methods
) to functions,
scala> val f1 = A.doFirstThing _
// f1: () => Unit = $$Lambda$1317/1501701470@7306836f
scala> val f2 = A.doSecondThing _
// f2: () => Unit = $$Lambda$1318/545144829@2a3251ad
Now, you can define your map using these,
scala> def execute(input: String): Unit = {
| val map = Map(
| "first" -> f1,
| "second" -> f2
| )
|
| map.get(input).foreach(f => f())
| }
// execute: (input: String)Unit
scala> execute("first")
// first thing :: 2
scala> execute("second")
// second thing :: 1
scala> execute("second")
// second thing :: 0
scala> execute("first")
// first thing :: 1
scala> execute("first")
// first thing :: 2
And it will plainly ignore all other inputs,
scala> execute("abc")
add a comment |
Yes, there is a way how to execute object methods inside a Map
. But you first have to put functions into the map. What you did, was putting results of object methods into your map. So your methods were executed and their results were put as values into the map.
Let's assume, that your methods are defined in this class:
class SomeObject {
def doStuff(): String = "I did stuff"
def doThing(): String = "I did a thing"
}
And you have an instance of the class:
val someObject = new SomeObject
First way, how to delay execution of these methods is to create new function using lambdas and execute methods inside these lambdas:
val actions = Map(
"foo" -> (() => someObject.doStuff()),
"bar" -> (() => someObject.doThing()),
)
You can use special syntax to convert object methods directly into lambdas:
val actions = Map(
"foo" -> someObject.doStuff _,
"bar" -> someObject.doThing _
)
If you specify type of the map explicitly, than you can get rid of the underscore too:
val actions: Map[String, () => String] = Map(
"foo" -> someObject.doStuff,
"bar" -> someObject.doThing
)
Next, you need to get the function from the map. If there is no function for the key, than use a default function - one, that always returns None
val action = actions.getOrElse(input, () => None)
And finally, you invoke the action:
action()
Please note, that the finalaction
returns either aString
orNone
. They do not share a reasonable common parent class. Return value of theaction
can therefore bejava.lang.Object
/scala.AnyRef
, orjava.io.Serializable
, none of those are too useful.
– ygor
Nov 17 '18 at 20:34
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53354256%2flazy-evaluation-in-a-map%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
object someObject {
def doStuff() = "foo"
def doThing() = "bar"
}
//if you need a string as a return value.
//there will be empty string for missing keys
def execute(input: String):String = {
val actions = Map( "foo" -> someObject.doStuff _ ,
"bar" -> someObject.doThing _ )
actions.getOrElse(input,()=>"")()
}
//if you need an Option[String] as a return value.
//there will be None value for missing keys
def executeOption(input: String):Option[String] = {
val actions = Map( "foo" -> someObject.doStuff _ ,
"bar" -> someObject.doThing _ )
actions.get(input).map(_())
}
Thanks, your executeOption was exactly what I was looking for. I was also wondering how to implement this when some of the functions in someObject take parameters?
– Kah
Nov 18 '18 at 14:14
this is quite complicated using pure scala. the problem is that in scala we can transform method into function literal using eta notation likesomeObject.doStuff _
, but function literals with parameters are not supported out of the box. There is a FunctionN type class in cats library that allows doing something like that using macros, but I'm not a very good at this staff.
– Bogdan Vakulenko
Nov 18 '18 at 14:22
add a comment |
object someObject {
def doStuff() = "foo"
def doThing() = "bar"
}
//if you need a string as a return value.
//there will be empty string for missing keys
def execute(input: String):String = {
val actions = Map( "foo" -> someObject.doStuff _ ,
"bar" -> someObject.doThing _ )
actions.getOrElse(input,()=>"")()
}
//if you need an Option[String] as a return value.
//there will be None value for missing keys
def executeOption(input: String):Option[String] = {
val actions = Map( "foo" -> someObject.doStuff _ ,
"bar" -> someObject.doThing _ )
actions.get(input).map(_())
}
Thanks, your executeOption was exactly what I was looking for. I was also wondering how to implement this when some of the functions in someObject take parameters?
– Kah
Nov 18 '18 at 14:14
this is quite complicated using pure scala. the problem is that in scala we can transform method into function literal using eta notation likesomeObject.doStuff _
, but function literals with parameters are not supported out of the box. There is a FunctionN type class in cats library that allows doing something like that using macros, but I'm not a very good at this staff.
– Bogdan Vakulenko
Nov 18 '18 at 14:22
add a comment |
object someObject {
def doStuff() = "foo"
def doThing() = "bar"
}
//if you need a string as a return value.
//there will be empty string for missing keys
def execute(input: String):String = {
val actions = Map( "foo" -> someObject.doStuff _ ,
"bar" -> someObject.doThing _ )
actions.getOrElse(input,()=>"")()
}
//if you need an Option[String] as a return value.
//there will be None value for missing keys
def executeOption(input: String):Option[String] = {
val actions = Map( "foo" -> someObject.doStuff _ ,
"bar" -> someObject.doThing _ )
actions.get(input).map(_())
}
object someObject {
def doStuff() = "foo"
def doThing() = "bar"
}
//if you need a string as a return value.
//there will be empty string for missing keys
def execute(input: String):String = {
val actions = Map( "foo" -> someObject.doStuff _ ,
"bar" -> someObject.doThing _ )
actions.getOrElse(input,()=>"")()
}
//if you need an Option[String] as a return value.
//there will be None value for missing keys
def executeOption(input: String):Option[String] = {
val actions = Map( "foo" -> someObject.doStuff _ ,
"bar" -> someObject.doThing _ )
actions.get(input).map(_())
}
edited Nov 18 '18 at 10:39
answered Nov 17 '18 at 20:31
Bogdan VakulenkoBogdan Vakulenko
1,006214
1,006214
Thanks, your executeOption was exactly what I was looking for. I was also wondering how to implement this when some of the functions in someObject take parameters?
– Kah
Nov 18 '18 at 14:14
this is quite complicated using pure scala. the problem is that in scala we can transform method into function literal using eta notation likesomeObject.doStuff _
, but function literals with parameters are not supported out of the box. There is a FunctionN type class in cats library that allows doing something like that using macros, but I'm not a very good at this staff.
– Bogdan Vakulenko
Nov 18 '18 at 14:22
add a comment |
Thanks, your executeOption was exactly what I was looking for. I was also wondering how to implement this when some of the functions in someObject take parameters?
– Kah
Nov 18 '18 at 14:14
this is quite complicated using pure scala. the problem is that in scala we can transform method into function literal using eta notation likesomeObject.doStuff _
, but function literals with parameters are not supported out of the box. There is a FunctionN type class in cats library that allows doing something like that using macros, but I'm not a very good at this staff.
– Bogdan Vakulenko
Nov 18 '18 at 14:22
Thanks, your executeOption was exactly what I was looking for. I was also wondering how to implement this when some of the functions in someObject take parameters?
– Kah
Nov 18 '18 at 14:14
Thanks, your executeOption was exactly what I was looking for. I was also wondering how to implement this when some of the functions in someObject take parameters?
– Kah
Nov 18 '18 at 14:14
this is quite complicated using pure scala. the problem is that in scala we can transform method into function literal using eta notation like
someObject.doStuff _
, but function literals with parameters are not supported out of the box. There is a FunctionN type class in cats library that allows doing something like that using macros, but I'm not a very good at this staff.– Bogdan Vakulenko
Nov 18 '18 at 14:22
this is quite complicated using pure scala. the problem is that in scala we can transform method into function literal using eta notation like
someObject.doStuff _
, but function literals with parameters are not supported out of the box. There is a FunctionN type class in cats library that allows doing something like that using macros, but I'm not a very good at this staff.– Bogdan Vakulenko
Nov 18 '18 at 14:22
add a comment |
From what I can tell, you are not really looking for lazy map
. You are trying to build some kind of execution engine, which does something based on string input.
Now, the simple trick to achieve this is to have a actual functions
in your Map
and execute the corresponding function for the input string.
So, lets say you have an object A,
object A {
var i = 1
def doFirstThing(): Unit = {
i = i + 1
println(s"first thing :: $i")
}
def doSecondThing(): Unit = {
i = i - 1
println(s"second thing :: $i")
}
}
And you want to build an executor for executing doFirstThing
for input "first"
and doSecondThing
for input "second"
.
So, now you need to create functions
f1
and f2
which will execute A.doFirstThing()
and A.doSecondThing()
.
Its pretty simple actually,
scala> val f1 = () => A.doFirstThing()
// f1: () => Unit = $$Lambda$1235/1187572055@7e192338
scala> val f2 = () => A.doSecondThing()
// f2: () => Unit = $$Lambda$1236/1696761182@47df3efe
Or, you can use _
to convert def
(methods
) to functions,
scala> val f1 = A.doFirstThing _
// f1: () => Unit = $$Lambda$1317/1501701470@7306836f
scala> val f2 = A.doSecondThing _
// f2: () => Unit = $$Lambda$1318/545144829@2a3251ad
Now, you can define your map using these,
scala> def execute(input: String): Unit = {
| val map = Map(
| "first" -> f1,
| "second" -> f2
| )
|
| map.get(input).foreach(f => f())
| }
// execute: (input: String)Unit
scala> execute("first")
// first thing :: 2
scala> execute("second")
// second thing :: 1
scala> execute("second")
// second thing :: 0
scala> execute("first")
// first thing :: 1
scala> execute("first")
// first thing :: 2
And it will plainly ignore all other inputs,
scala> execute("abc")
add a comment |
From what I can tell, you are not really looking for lazy map
. You are trying to build some kind of execution engine, which does something based on string input.
Now, the simple trick to achieve this is to have a actual functions
in your Map
and execute the corresponding function for the input string.
So, lets say you have an object A,
object A {
var i = 1
def doFirstThing(): Unit = {
i = i + 1
println(s"first thing :: $i")
}
def doSecondThing(): Unit = {
i = i - 1
println(s"second thing :: $i")
}
}
And you want to build an executor for executing doFirstThing
for input "first"
and doSecondThing
for input "second"
.
So, now you need to create functions
f1
and f2
which will execute A.doFirstThing()
and A.doSecondThing()
.
Its pretty simple actually,
scala> val f1 = () => A.doFirstThing()
// f1: () => Unit = $$Lambda$1235/1187572055@7e192338
scala> val f2 = () => A.doSecondThing()
// f2: () => Unit = $$Lambda$1236/1696761182@47df3efe
Or, you can use _
to convert def
(methods
) to functions,
scala> val f1 = A.doFirstThing _
// f1: () => Unit = $$Lambda$1317/1501701470@7306836f
scala> val f2 = A.doSecondThing _
// f2: () => Unit = $$Lambda$1318/545144829@2a3251ad
Now, you can define your map using these,
scala> def execute(input: String): Unit = {
| val map = Map(
| "first" -> f1,
| "second" -> f2
| )
|
| map.get(input).foreach(f => f())
| }
// execute: (input: String)Unit
scala> execute("first")
// first thing :: 2
scala> execute("second")
// second thing :: 1
scala> execute("second")
// second thing :: 0
scala> execute("first")
// first thing :: 1
scala> execute("first")
// first thing :: 2
And it will plainly ignore all other inputs,
scala> execute("abc")
add a comment |
From what I can tell, you are not really looking for lazy map
. You are trying to build some kind of execution engine, which does something based on string input.
Now, the simple trick to achieve this is to have a actual functions
in your Map
and execute the corresponding function for the input string.
So, lets say you have an object A,
object A {
var i = 1
def doFirstThing(): Unit = {
i = i + 1
println(s"first thing :: $i")
}
def doSecondThing(): Unit = {
i = i - 1
println(s"second thing :: $i")
}
}
And you want to build an executor for executing doFirstThing
for input "first"
and doSecondThing
for input "second"
.
So, now you need to create functions
f1
and f2
which will execute A.doFirstThing()
and A.doSecondThing()
.
Its pretty simple actually,
scala> val f1 = () => A.doFirstThing()
// f1: () => Unit = $$Lambda$1235/1187572055@7e192338
scala> val f2 = () => A.doSecondThing()
// f2: () => Unit = $$Lambda$1236/1696761182@47df3efe
Or, you can use _
to convert def
(methods
) to functions,
scala> val f1 = A.doFirstThing _
// f1: () => Unit = $$Lambda$1317/1501701470@7306836f
scala> val f2 = A.doSecondThing _
// f2: () => Unit = $$Lambda$1318/545144829@2a3251ad
Now, you can define your map using these,
scala> def execute(input: String): Unit = {
| val map = Map(
| "first" -> f1,
| "second" -> f2
| )
|
| map.get(input).foreach(f => f())
| }
// execute: (input: String)Unit
scala> execute("first")
// first thing :: 2
scala> execute("second")
// second thing :: 1
scala> execute("second")
// second thing :: 0
scala> execute("first")
// first thing :: 1
scala> execute("first")
// first thing :: 2
And it will plainly ignore all other inputs,
scala> execute("abc")
From what I can tell, you are not really looking for lazy map
. You are trying to build some kind of execution engine, which does something based on string input.
Now, the simple trick to achieve this is to have a actual functions
in your Map
and execute the corresponding function for the input string.
So, lets say you have an object A,
object A {
var i = 1
def doFirstThing(): Unit = {
i = i + 1
println(s"first thing :: $i")
}
def doSecondThing(): Unit = {
i = i - 1
println(s"second thing :: $i")
}
}
And you want to build an executor for executing doFirstThing
for input "first"
and doSecondThing
for input "second"
.
So, now you need to create functions
f1
and f2
which will execute A.doFirstThing()
and A.doSecondThing()
.
Its pretty simple actually,
scala> val f1 = () => A.doFirstThing()
// f1: () => Unit = $$Lambda$1235/1187572055@7e192338
scala> val f2 = () => A.doSecondThing()
// f2: () => Unit = $$Lambda$1236/1696761182@47df3efe
Or, you can use _
to convert def
(methods
) to functions,
scala> val f1 = A.doFirstThing _
// f1: () => Unit = $$Lambda$1317/1501701470@7306836f
scala> val f2 = A.doSecondThing _
// f2: () => Unit = $$Lambda$1318/545144829@2a3251ad
Now, you can define your map using these,
scala> def execute(input: String): Unit = {
| val map = Map(
| "first" -> f1,
| "second" -> f2
| )
|
| map.get(input).foreach(f => f())
| }
// execute: (input: String)Unit
scala> execute("first")
// first thing :: 2
scala> execute("second")
// second thing :: 1
scala> execute("second")
// second thing :: 0
scala> execute("first")
// first thing :: 1
scala> execute("first")
// first thing :: 2
And it will plainly ignore all other inputs,
scala> execute("abc")
edited Nov 17 '18 at 20:19
answered Nov 17 '18 at 20:07
Sarvesh Kumar SinghSarvesh Kumar Singh
8,3311935
8,3311935
add a comment |
add a comment |
Yes, there is a way how to execute object methods inside a Map
. But you first have to put functions into the map. What you did, was putting results of object methods into your map. So your methods were executed and their results were put as values into the map.
Let's assume, that your methods are defined in this class:
class SomeObject {
def doStuff(): String = "I did stuff"
def doThing(): String = "I did a thing"
}
And you have an instance of the class:
val someObject = new SomeObject
First way, how to delay execution of these methods is to create new function using lambdas and execute methods inside these lambdas:
val actions = Map(
"foo" -> (() => someObject.doStuff()),
"bar" -> (() => someObject.doThing()),
)
You can use special syntax to convert object methods directly into lambdas:
val actions = Map(
"foo" -> someObject.doStuff _,
"bar" -> someObject.doThing _
)
If you specify type of the map explicitly, than you can get rid of the underscore too:
val actions: Map[String, () => String] = Map(
"foo" -> someObject.doStuff,
"bar" -> someObject.doThing
)
Next, you need to get the function from the map. If there is no function for the key, than use a default function - one, that always returns None
val action = actions.getOrElse(input, () => None)
And finally, you invoke the action:
action()
Please note, that the finalaction
returns either aString
orNone
. They do not share a reasonable common parent class. Return value of theaction
can therefore bejava.lang.Object
/scala.AnyRef
, orjava.io.Serializable
, none of those are too useful.
– ygor
Nov 17 '18 at 20:34
add a comment |
Yes, there is a way how to execute object methods inside a Map
. But you first have to put functions into the map. What you did, was putting results of object methods into your map. So your methods were executed and their results were put as values into the map.
Let's assume, that your methods are defined in this class:
class SomeObject {
def doStuff(): String = "I did stuff"
def doThing(): String = "I did a thing"
}
And you have an instance of the class:
val someObject = new SomeObject
First way, how to delay execution of these methods is to create new function using lambdas and execute methods inside these lambdas:
val actions = Map(
"foo" -> (() => someObject.doStuff()),
"bar" -> (() => someObject.doThing()),
)
You can use special syntax to convert object methods directly into lambdas:
val actions = Map(
"foo" -> someObject.doStuff _,
"bar" -> someObject.doThing _
)
If you specify type of the map explicitly, than you can get rid of the underscore too:
val actions: Map[String, () => String] = Map(
"foo" -> someObject.doStuff,
"bar" -> someObject.doThing
)
Next, you need to get the function from the map. If there is no function for the key, than use a default function - one, that always returns None
val action = actions.getOrElse(input, () => None)
And finally, you invoke the action:
action()
Please note, that the finalaction
returns either aString
orNone
. They do not share a reasonable common parent class. Return value of theaction
can therefore bejava.lang.Object
/scala.AnyRef
, orjava.io.Serializable
, none of those are too useful.
– ygor
Nov 17 '18 at 20:34
add a comment |
Yes, there is a way how to execute object methods inside a Map
. But you first have to put functions into the map. What you did, was putting results of object methods into your map. So your methods were executed and their results were put as values into the map.
Let's assume, that your methods are defined in this class:
class SomeObject {
def doStuff(): String = "I did stuff"
def doThing(): String = "I did a thing"
}
And you have an instance of the class:
val someObject = new SomeObject
First way, how to delay execution of these methods is to create new function using lambdas and execute methods inside these lambdas:
val actions = Map(
"foo" -> (() => someObject.doStuff()),
"bar" -> (() => someObject.doThing()),
)
You can use special syntax to convert object methods directly into lambdas:
val actions = Map(
"foo" -> someObject.doStuff _,
"bar" -> someObject.doThing _
)
If you specify type of the map explicitly, than you can get rid of the underscore too:
val actions: Map[String, () => String] = Map(
"foo" -> someObject.doStuff,
"bar" -> someObject.doThing
)
Next, you need to get the function from the map. If there is no function for the key, than use a default function - one, that always returns None
val action = actions.getOrElse(input, () => None)
And finally, you invoke the action:
action()
Yes, there is a way how to execute object methods inside a Map
. But you first have to put functions into the map. What you did, was putting results of object methods into your map. So your methods were executed and their results were put as values into the map.
Let's assume, that your methods are defined in this class:
class SomeObject {
def doStuff(): String = "I did stuff"
def doThing(): String = "I did a thing"
}
And you have an instance of the class:
val someObject = new SomeObject
First way, how to delay execution of these methods is to create new function using lambdas and execute methods inside these lambdas:
val actions = Map(
"foo" -> (() => someObject.doStuff()),
"bar" -> (() => someObject.doThing()),
)
You can use special syntax to convert object methods directly into lambdas:
val actions = Map(
"foo" -> someObject.doStuff _,
"bar" -> someObject.doThing _
)
If you specify type of the map explicitly, than you can get rid of the underscore too:
val actions: Map[String, () => String] = Map(
"foo" -> someObject.doStuff,
"bar" -> someObject.doThing
)
Next, you need to get the function from the map. If there is no function for the key, than use a default function - one, that always returns None
val action = actions.getOrElse(input, () => None)
And finally, you invoke the action:
action()
edited Nov 17 '18 at 20:37
answered Nov 17 '18 at 20:26
ygorygor
1,111615
1,111615
Please note, that the finalaction
returns either aString
orNone
. They do not share a reasonable common parent class. Return value of theaction
can therefore bejava.lang.Object
/scala.AnyRef
, orjava.io.Serializable
, none of those are too useful.
– ygor
Nov 17 '18 at 20:34
add a comment |
Please note, that the finalaction
returns either aString
orNone
. They do not share a reasonable common parent class. Return value of theaction
can therefore bejava.lang.Object
/scala.AnyRef
, orjava.io.Serializable
, none of those are too useful.
– ygor
Nov 17 '18 at 20:34
Please note, that the final
action
returns either a String
or None
. They do not share a reasonable common parent class. Return value of the action
can therefore be java.lang.Object
/ scala.AnyRef
, or java.io.Serializable
, none of those are too useful.– ygor
Nov 17 '18 at 20:34
Please note, that the final
action
returns either a String
or None
. They do not share a reasonable common parent class. Return value of the action
can therefore be java.lang.Object
/ scala.AnyRef
, or java.io.Serializable
, none of those are too useful.– ygor
Nov 17 '18 at 20:34
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53354256%2flazy-evaluation-in-a-map%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
what is the default function you want to call if key is doesn't exist?
– Raman Mishra
Nov 17 '18 at 18:44
Then None should be returned.
– Kah
Nov 17 '18 at 18:53
You can start with something like:
if (actions isDefinedAt input) actions.get(input) else None
. Better yet, try to usescala.util.Try
!– jrook
Nov 17 '18 at 19:55
I think the only way to do this is to convert the values to a thunk.
– erip
Nov 17 '18 at 20:42
2
@jrook
Map#get
already returns anOption[T]
-- no need to checkisDefinedAt
.– erip
Nov 18 '18 at 2:52