Lazy evaluation in a Map












3















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?










share|improve this question

























  • 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 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






  • 2





    @jrook Map#get already returns an Option[T] -- no need to check isDefinedAt.

    – erip
    Nov 18 '18 at 2:52
















3















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?










share|improve this question

























  • 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 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






  • 2





    @jrook Map#get already returns an Option[T] -- no need to check isDefinedAt.

    – erip
    Nov 18 '18 at 2:52














3












3








3








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?










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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 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






  • 2





    @jrook Map#get already returns an Option[T] -- no need to check isDefinedAt.

    – 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











  • 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











  • 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 an Option[T] -- no need to check isDefinedAt.

    – 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












3 Answers
3






active

oldest

votes


















4














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(_())
}





share|improve this answer


























  • 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





















1














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")





share|improve this answer

































    1














    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()





    share|improve this answer


























    • 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











    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
    });


    }
    });














    draft saved

    draft discarded


















    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









    4














    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(_())
    }





    share|improve this answer


























    • 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


















    4














    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(_())
    }





    share|improve this answer


























    • 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
















    4












    4








    4







    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(_())
    }





    share|improve this answer















    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(_())
    }






    share|improve this answer














    share|improve this answer



    share|improve this answer








    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 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





















    • 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



















    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















    1














    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")





    share|improve this answer






























      1














      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")





      share|improve this answer




























        1












        1








        1







        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")





        share|improve this answer















        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")






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 17 '18 at 20:19

























        answered Nov 17 '18 at 20:07









        Sarvesh Kumar SinghSarvesh Kumar Singh

        8,3311935




        8,3311935























            1














            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()





            share|improve this answer


























            • 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
















            1














            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()





            share|improve this answer


























            • 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














            1












            1








            1







            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()





            share|improve this answer















            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()






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 17 '18 at 20:37

























            answered Nov 17 '18 at 20:26









            ygorygor

            1,111615




            1,111615













            • 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

















            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


















            draft saved

            draft discarded




















































            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.




            draft saved


            draft discarded














            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





















































            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







            這個網誌中的熱門文章

            Xamarin.form Move up view when keyboard appear

            Post-Redirect-Get with Spring WebFlux and Thymeleaf

            Anylogic : not able to use stopDelay()