Function to cache its argument's return value












20















I want to write a function once that accepts a callback as input and returns a function. When the returned function is called the first time, it should call the callback and return that output. If it is called any additional times, instead of calling the callback again it will simply return the output value from the first time it was called.



Below is what I have tried to do. But I am not getting the results as I expected. I need to understand this concept.



function once(func) {
let num;
function retFunc(x){
num = func(x);
return num;
}
return retFunc;
}

function addByTwo(input){
return input + 2;
}

var onceFunc = once(addByTwo);

console.log(onceFunc(4)); //should log 6
console.log(onceFunc(10)); //should log 6
console.log(onceFunc(9001)); //should log 6









share|improve this question




















  • 1





    The num is already a good first step, but how do you remember that it was called a first time already? You always overwrite num = func(x)

    – Bergi
    Jan 7 at 7:29











  • FYI, this is called memoization

    – Barmar
    Jan 7 at 17:14
















20















I want to write a function once that accepts a callback as input and returns a function. When the returned function is called the first time, it should call the callback and return that output. If it is called any additional times, instead of calling the callback again it will simply return the output value from the first time it was called.



Below is what I have tried to do. But I am not getting the results as I expected. I need to understand this concept.



function once(func) {
let num;
function retFunc(x){
num = func(x);
return num;
}
return retFunc;
}

function addByTwo(input){
return input + 2;
}

var onceFunc = once(addByTwo);

console.log(onceFunc(4)); //should log 6
console.log(onceFunc(10)); //should log 6
console.log(onceFunc(9001)); //should log 6









share|improve this question




















  • 1





    The num is already a good first step, but how do you remember that it was called a first time already? You always overwrite num = func(x)

    – Bergi
    Jan 7 at 7:29











  • FYI, this is called memoization

    – Barmar
    Jan 7 at 17:14














20












20








20


1






I want to write a function once that accepts a callback as input and returns a function. When the returned function is called the first time, it should call the callback and return that output. If it is called any additional times, instead of calling the callback again it will simply return the output value from the first time it was called.



Below is what I have tried to do. But I am not getting the results as I expected. I need to understand this concept.



function once(func) {
let num;
function retFunc(x){
num = func(x);
return num;
}
return retFunc;
}

function addByTwo(input){
return input + 2;
}

var onceFunc = once(addByTwo);

console.log(onceFunc(4)); //should log 6
console.log(onceFunc(10)); //should log 6
console.log(onceFunc(9001)); //should log 6









share|improve this question
















I want to write a function once that accepts a callback as input and returns a function. When the returned function is called the first time, it should call the callback and return that output. If it is called any additional times, instead of calling the callback again it will simply return the output value from the first time it was called.



Below is what I have tried to do. But I am not getting the results as I expected. I need to understand this concept.



function once(func) {
let num;
function retFunc(x){
num = func(x);
return num;
}
return retFunc;
}

function addByTwo(input){
return input + 2;
}

var onceFunc = once(addByTwo);

console.log(onceFunc(4)); //should log 6
console.log(onceFunc(10)); //should log 6
console.log(onceFunc(9001)); //should log 6






javascript memoization






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 7 at 17:14









Barmar

434k36258359




434k36258359










asked Jan 7 at 7:22









Amit KumarAmit Kumar

1368




1368








  • 1





    The num is already a good first step, but how do you remember that it was called a first time already? You always overwrite num = func(x)

    – Bergi
    Jan 7 at 7:29











  • FYI, this is called memoization

    – Barmar
    Jan 7 at 17:14














  • 1





    The num is already a good first step, but how do you remember that it was called a first time already? You always overwrite num = func(x)

    – Bergi
    Jan 7 at 7:29











  • FYI, this is called memoization

    – Barmar
    Jan 7 at 17:14








1




1





The num is already a good first step, but how do you remember that it was called a first time already? You always overwrite num = func(x)

– Bergi
Jan 7 at 7:29





The num is already a good first step, but how do you remember that it was called a first time already? You always overwrite num = func(x)

– Bergi
Jan 7 at 7:29













FYI, this is called memoization

– Barmar
Jan 7 at 17:14





FYI, this is called memoization

– Barmar
Jan 7 at 17:14












5 Answers
5






active

oldest

votes


















19














You should only assign num = func(x) when num is undefined - that is, on the very first call of retFunc:






function once(func) {
let num;
function retFunc(x){
if (num === undefined) {
num = func(x);
}
return num;
}
return retFunc;
}

function addByTwo(input){
return input + 2;
}

var onceFunc = once(addByTwo);

console.log(onceFunc(4)); //should log 6
console.log(onceFunc(10)); //should log 6
console.log(onceFunc(9001)); //should log 6





But this isn't a guaranteed general solution - what if the passed function (addByTwo in your example) results in undefined when called? Then, the === undefined check won't work. So, it might be better to set a flag or something similar, and reassign that flag the first time the callback is called:






function once(func) {
let num;
let done = false;
function retFunc(x){
if (!done) {
done = true;
num = func(x);
}
return num;
}
return retFunc;
}

function returnsUndefinedOn1(input){
return input === 1 ? undefined : input;
}

var onceFunc = once(returnsUndefinedOn1);

console.log(onceFunc(1));
console.log(onceFunc(10));
console.log(onceFunc(9001));








share|improve this answer



















  • 2





    That's the desired behavior - on an input of 1, the function returnsUndefinedOn1 returns undefined, per its name. Further calls of onceFunc will also return undefined, despite being called with an argument other than 1.

    – CertainPerformance
    Jan 7 at 7:39






  • 2





    Please use typeof to compare with undefined

    – Pierre Arlaud
    Jan 7 at 8:39






  • 2





    @PierreArlaud In any remotely reasonable code, it shouldn't be necessary, I think? Many global object can be redefined, that doesn't mean they shouldn't be used, that means not to reassign them.

    – CertainPerformance
    Jan 7 at 8:43






  • 1





    @CertainPerformance typeof also does not trigger an exception if the variable is not declared. There is no scenario where not using typeof to compare with undefined is the better choice. My opinion on the matter is that using typeof is a good habbit to have, and "remotely reasonable codes" are no exceptions.

    – Pierre Arlaud
    Jan 7 at 8:47






  • 3





    @PierreArlaud: In this case, getting an exception if the variable is not declared is desirable, since we're trying to test the value of a variable we know we just declared, and the exception is telling us that we made a typo in the variable name and the code is broken.

    – Ilmari Karonen
    Jan 7 at 11:39





















8














You should only call the function and assign num if it's undefined, otherwise you overwrite it every time:






function once(func) {
let num;

function retFunc(x) {
num = (num === undefined) ? func(x) : num
return num;
}
return retFunc;
}

function addByTwo(input) {
return input + 2;
}

var onceFunc = once(addByTwo);

console.log(onceFunc(4)); //should log 6
console.log(onceFunc(10)); //should log 6
console.log(onceFunc(9001)); //should log 6





Note that if the function you pass in returns undefined it will be called more than once. If you need to handle that case you can set a flag to indicate whether the cached value is valid.






share|improve this answer


























  • wow, you're really helpful around here aren't ya? no wonder you have 36.8k rep

    – Yang K
    Jan 7 at 7:30











  • @YangK mostly insomnia!

    – Mark Meyer
    Jan 7 at 7:31











  • same here but not as smart or helpful as you lol

    – Yang K
    Jan 7 at 7:43



















4














What you're missing is removing the original function after the first execution. You should modify your code in the following way:



function once(func) {
let num;
function retFunc(x){
if (func)
num = func(x);
func = null;
return num;
}
return retFunc;
}

function addByTwo(input){
return input + 2;
}

var onceFunc = once(addByTwo);

console.log(onceFunc(4)); //should log 6
console.log(onceFunc(10)); //should log 6
console.log(onceFunc(9001)); //should log 6


This way you remove the function after first usage and you're just keeping the result.






share|improve this answer
























  • Also i'd like to say that this way is better than relying on the result, because function doesn't need to always return something. It may return undefined, but we still want to run it only once.

    – tswistak
    Jan 7 at 11:51



















3














This is your problem



function retFunc(x){
num = func(x);
return num;
}


You're always calling func(x). Add an if condition to check if num is undefined before calling func(x).






share|improve this answer
























  • Hi by adding if condition to check whether num is undefined my code is working now.

    – Amit Kumar
    Jan 7 at 7:31





















2














different approach: overwrite the call to func



no flags, check if result is undefined or anything required



function once(func) {
let num;

let internalFn = function(x) {
num = func(x);
internalFn = function(x) {
return num;
}
return num;
}

function retFunc(x){
return internalFn(x);
}
return retFunc;
}

function addByTwo(input){
return input + 2;
}

var onceFunc = once(addByTwo);

console.log(onceFunc(4)); //should log 6
console.log(onceFunc(10)); //should log 6
console.log(onceFunc(9001)); //should log 6





share|improve this answer























    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%2f54070049%2ffunction-to-cache-its-arguments-return-value%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    5 Answers
    5






    active

    oldest

    votes








    5 Answers
    5






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    19














    You should only assign num = func(x) when num is undefined - that is, on the very first call of retFunc:






    function once(func) {
    let num;
    function retFunc(x){
    if (num === undefined) {
    num = func(x);
    }
    return num;
    }
    return retFunc;
    }

    function addByTwo(input){
    return input + 2;
    }

    var onceFunc = once(addByTwo);

    console.log(onceFunc(4)); //should log 6
    console.log(onceFunc(10)); //should log 6
    console.log(onceFunc(9001)); //should log 6





    But this isn't a guaranteed general solution - what if the passed function (addByTwo in your example) results in undefined when called? Then, the === undefined check won't work. So, it might be better to set a flag or something similar, and reassign that flag the first time the callback is called:






    function once(func) {
    let num;
    let done = false;
    function retFunc(x){
    if (!done) {
    done = true;
    num = func(x);
    }
    return num;
    }
    return retFunc;
    }

    function returnsUndefinedOn1(input){
    return input === 1 ? undefined : input;
    }

    var onceFunc = once(returnsUndefinedOn1);

    console.log(onceFunc(1));
    console.log(onceFunc(10));
    console.log(onceFunc(9001));








    share|improve this answer



















    • 2





      That's the desired behavior - on an input of 1, the function returnsUndefinedOn1 returns undefined, per its name. Further calls of onceFunc will also return undefined, despite being called with an argument other than 1.

      – CertainPerformance
      Jan 7 at 7:39






    • 2





      Please use typeof to compare with undefined

      – Pierre Arlaud
      Jan 7 at 8:39






    • 2





      @PierreArlaud In any remotely reasonable code, it shouldn't be necessary, I think? Many global object can be redefined, that doesn't mean they shouldn't be used, that means not to reassign them.

      – CertainPerformance
      Jan 7 at 8:43






    • 1





      @CertainPerformance typeof also does not trigger an exception if the variable is not declared. There is no scenario where not using typeof to compare with undefined is the better choice. My opinion on the matter is that using typeof is a good habbit to have, and "remotely reasonable codes" are no exceptions.

      – Pierre Arlaud
      Jan 7 at 8:47






    • 3





      @PierreArlaud: In this case, getting an exception if the variable is not declared is desirable, since we're trying to test the value of a variable we know we just declared, and the exception is telling us that we made a typo in the variable name and the code is broken.

      – Ilmari Karonen
      Jan 7 at 11:39


















    19














    You should only assign num = func(x) when num is undefined - that is, on the very first call of retFunc:






    function once(func) {
    let num;
    function retFunc(x){
    if (num === undefined) {
    num = func(x);
    }
    return num;
    }
    return retFunc;
    }

    function addByTwo(input){
    return input + 2;
    }

    var onceFunc = once(addByTwo);

    console.log(onceFunc(4)); //should log 6
    console.log(onceFunc(10)); //should log 6
    console.log(onceFunc(9001)); //should log 6





    But this isn't a guaranteed general solution - what if the passed function (addByTwo in your example) results in undefined when called? Then, the === undefined check won't work. So, it might be better to set a flag or something similar, and reassign that flag the first time the callback is called:






    function once(func) {
    let num;
    let done = false;
    function retFunc(x){
    if (!done) {
    done = true;
    num = func(x);
    }
    return num;
    }
    return retFunc;
    }

    function returnsUndefinedOn1(input){
    return input === 1 ? undefined : input;
    }

    var onceFunc = once(returnsUndefinedOn1);

    console.log(onceFunc(1));
    console.log(onceFunc(10));
    console.log(onceFunc(9001));








    share|improve this answer



















    • 2





      That's the desired behavior - on an input of 1, the function returnsUndefinedOn1 returns undefined, per its name. Further calls of onceFunc will also return undefined, despite being called with an argument other than 1.

      – CertainPerformance
      Jan 7 at 7:39






    • 2





      Please use typeof to compare with undefined

      – Pierre Arlaud
      Jan 7 at 8:39






    • 2





      @PierreArlaud In any remotely reasonable code, it shouldn't be necessary, I think? Many global object can be redefined, that doesn't mean they shouldn't be used, that means not to reassign them.

      – CertainPerformance
      Jan 7 at 8:43






    • 1





      @CertainPerformance typeof also does not trigger an exception if the variable is not declared. There is no scenario where not using typeof to compare with undefined is the better choice. My opinion on the matter is that using typeof is a good habbit to have, and "remotely reasonable codes" are no exceptions.

      – Pierre Arlaud
      Jan 7 at 8:47






    • 3





      @PierreArlaud: In this case, getting an exception if the variable is not declared is desirable, since we're trying to test the value of a variable we know we just declared, and the exception is telling us that we made a typo in the variable name and the code is broken.

      – Ilmari Karonen
      Jan 7 at 11:39
















    19












    19








    19







    You should only assign num = func(x) when num is undefined - that is, on the very first call of retFunc:






    function once(func) {
    let num;
    function retFunc(x){
    if (num === undefined) {
    num = func(x);
    }
    return num;
    }
    return retFunc;
    }

    function addByTwo(input){
    return input + 2;
    }

    var onceFunc = once(addByTwo);

    console.log(onceFunc(4)); //should log 6
    console.log(onceFunc(10)); //should log 6
    console.log(onceFunc(9001)); //should log 6





    But this isn't a guaranteed general solution - what if the passed function (addByTwo in your example) results in undefined when called? Then, the === undefined check won't work. So, it might be better to set a flag or something similar, and reassign that flag the first time the callback is called:






    function once(func) {
    let num;
    let done = false;
    function retFunc(x){
    if (!done) {
    done = true;
    num = func(x);
    }
    return num;
    }
    return retFunc;
    }

    function returnsUndefinedOn1(input){
    return input === 1 ? undefined : input;
    }

    var onceFunc = once(returnsUndefinedOn1);

    console.log(onceFunc(1));
    console.log(onceFunc(10));
    console.log(onceFunc(9001));








    share|improve this answer













    You should only assign num = func(x) when num is undefined - that is, on the very first call of retFunc:






    function once(func) {
    let num;
    function retFunc(x){
    if (num === undefined) {
    num = func(x);
    }
    return num;
    }
    return retFunc;
    }

    function addByTwo(input){
    return input + 2;
    }

    var onceFunc = once(addByTwo);

    console.log(onceFunc(4)); //should log 6
    console.log(onceFunc(10)); //should log 6
    console.log(onceFunc(9001)); //should log 6





    But this isn't a guaranteed general solution - what if the passed function (addByTwo in your example) results in undefined when called? Then, the === undefined check won't work. So, it might be better to set a flag or something similar, and reassign that flag the first time the callback is called:






    function once(func) {
    let num;
    let done = false;
    function retFunc(x){
    if (!done) {
    done = true;
    num = func(x);
    }
    return num;
    }
    return retFunc;
    }

    function returnsUndefinedOn1(input){
    return input === 1 ? undefined : input;
    }

    var onceFunc = once(returnsUndefinedOn1);

    console.log(onceFunc(1));
    console.log(onceFunc(10));
    console.log(onceFunc(9001));








    function once(func) {
    let num;
    function retFunc(x){
    if (num === undefined) {
    num = func(x);
    }
    return num;
    }
    return retFunc;
    }

    function addByTwo(input){
    return input + 2;
    }

    var onceFunc = once(addByTwo);

    console.log(onceFunc(4)); //should log 6
    console.log(onceFunc(10)); //should log 6
    console.log(onceFunc(9001)); //should log 6





    function once(func) {
    let num;
    function retFunc(x){
    if (num === undefined) {
    num = func(x);
    }
    return num;
    }
    return retFunc;
    }

    function addByTwo(input){
    return input + 2;
    }

    var onceFunc = once(addByTwo);

    console.log(onceFunc(4)); //should log 6
    console.log(onceFunc(10)); //should log 6
    console.log(onceFunc(9001)); //should log 6





    function once(func) {
    let num;
    let done = false;
    function retFunc(x){
    if (!done) {
    done = true;
    num = func(x);
    }
    return num;
    }
    return retFunc;
    }

    function returnsUndefinedOn1(input){
    return input === 1 ? undefined : input;
    }

    var onceFunc = once(returnsUndefinedOn1);

    console.log(onceFunc(1));
    console.log(onceFunc(10));
    console.log(onceFunc(9001));





    function once(func) {
    let num;
    let done = false;
    function retFunc(x){
    if (!done) {
    done = true;
    num = func(x);
    }
    return num;
    }
    return retFunc;
    }

    function returnsUndefinedOn1(input){
    return input === 1 ? undefined : input;
    }

    var onceFunc = once(returnsUndefinedOn1);

    console.log(onceFunc(1));
    console.log(onceFunc(10));
    console.log(onceFunc(9001));






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Jan 7 at 7:29









    CertainPerformanceCertainPerformance

    95.5k165786




    95.5k165786








    • 2





      That's the desired behavior - on an input of 1, the function returnsUndefinedOn1 returns undefined, per its name. Further calls of onceFunc will also return undefined, despite being called with an argument other than 1.

      – CertainPerformance
      Jan 7 at 7:39






    • 2





      Please use typeof to compare with undefined

      – Pierre Arlaud
      Jan 7 at 8:39






    • 2





      @PierreArlaud In any remotely reasonable code, it shouldn't be necessary, I think? Many global object can be redefined, that doesn't mean they shouldn't be used, that means not to reassign them.

      – CertainPerformance
      Jan 7 at 8:43






    • 1





      @CertainPerformance typeof also does not trigger an exception if the variable is not declared. There is no scenario where not using typeof to compare with undefined is the better choice. My opinion on the matter is that using typeof is a good habbit to have, and "remotely reasonable codes" are no exceptions.

      – Pierre Arlaud
      Jan 7 at 8:47






    • 3





      @PierreArlaud: In this case, getting an exception if the variable is not declared is desirable, since we're trying to test the value of a variable we know we just declared, and the exception is telling us that we made a typo in the variable name and the code is broken.

      – Ilmari Karonen
      Jan 7 at 11:39
















    • 2





      That's the desired behavior - on an input of 1, the function returnsUndefinedOn1 returns undefined, per its name. Further calls of onceFunc will also return undefined, despite being called with an argument other than 1.

      – CertainPerformance
      Jan 7 at 7:39






    • 2





      Please use typeof to compare with undefined

      – Pierre Arlaud
      Jan 7 at 8:39






    • 2





      @PierreArlaud In any remotely reasonable code, it shouldn't be necessary, I think? Many global object can be redefined, that doesn't mean they shouldn't be used, that means not to reassign them.

      – CertainPerformance
      Jan 7 at 8:43






    • 1





      @CertainPerformance typeof also does not trigger an exception if the variable is not declared. There is no scenario where not using typeof to compare with undefined is the better choice. My opinion on the matter is that using typeof is a good habbit to have, and "remotely reasonable codes" are no exceptions.

      – Pierre Arlaud
      Jan 7 at 8:47






    • 3





      @PierreArlaud: In this case, getting an exception if the variable is not declared is desirable, since we're trying to test the value of a variable we know we just declared, and the exception is telling us that we made a typo in the variable name and the code is broken.

      – Ilmari Karonen
      Jan 7 at 11:39










    2




    2





    That's the desired behavior - on an input of 1, the function returnsUndefinedOn1 returns undefined, per its name. Further calls of onceFunc will also return undefined, despite being called with an argument other than 1.

    – CertainPerformance
    Jan 7 at 7:39





    That's the desired behavior - on an input of 1, the function returnsUndefinedOn1 returns undefined, per its name. Further calls of onceFunc will also return undefined, despite being called with an argument other than 1.

    – CertainPerformance
    Jan 7 at 7:39




    2




    2





    Please use typeof to compare with undefined

    – Pierre Arlaud
    Jan 7 at 8:39





    Please use typeof to compare with undefined

    – Pierre Arlaud
    Jan 7 at 8:39




    2




    2





    @PierreArlaud In any remotely reasonable code, it shouldn't be necessary, I think? Many global object can be redefined, that doesn't mean they shouldn't be used, that means not to reassign them.

    – CertainPerformance
    Jan 7 at 8:43





    @PierreArlaud In any remotely reasonable code, it shouldn't be necessary, I think? Many global object can be redefined, that doesn't mean they shouldn't be used, that means not to reassign them.

    – CertainPerformance
    Jan 7 at 8:43




    1




    1





    @CertainPerformance typeof also does not trigger an exception if the variable is not declared. There is no scenario where not using typeof to compare with undefined is the better choice. My opinion on the matter is that using typeof is a good habbit to have, and "remotely reasonable codes" are no exceptions.

    – Pierre Arlaud
    Jan 7 at 8:47





    @CertainPerformance typeof also does not trigger an exception if the variable is not declared. There is no scenario where not using typeof to compare with undefined is the better choice. My opinion on the matter is that using typeof is a good habbit to have, and "remotely reasonable codes" are no exceptions.

    – Pierre Arlaud
    Jan 7 at 8:47




    3




    3





    @PierreArlaud: In this case, getting an exception if the variable is not declared is desirable, since we're trying to test the value of a variable we know we just declared, and the exception is telling us that we made a typo in the variable name and the code is broken.

    – Ilmari Karonen
    Jan 7 at 11:39







    @PierreArlaud: In this case, getting an exception if the variable is not declared is desirable, since we're trying to test the value of a variable we know we just declared, and the exception is telling us that we made a typo in the variable name and the code is broken.

    – Ilmari Karonen
    Jan 7 at 11:39















    8














    You should only call the function and assign num if it's undefined, otherwise you overwrite it every time:






    function once(func) {
    let num;

    function retFunc(x) {
    num = (num === undefined) ? func(x) : num
    return num;
    }
    return retFunc;
    }

    function addByTwo(input) {
    return input + 2;
    }

    var onceFunc = once(addByTwo);

    console.log(onceFunc(4)); //should log 6
    console.log(onceFunc(10)); //should log 6
    console.log(onceFunc(9001)); //should log 6





    Note that if the function you pass in returns undefined it will be called more than once. If you need to handle that case you can set a flag to indicate whether the cached value is valid.






    share|improve this answer


























    • wow, you're really helpful around here aren't ya? no wonder you have 36.8k rep

      – Yang K
      Jan 7 at 7:30











    • @YangK mostly insomnia!

      – Mark Meyer
      Jan 7 at 7:31











    • same here but not as smart or helpful as you lol

      – Yang K
      Jan 7 at 7:43
















    8














    You should only call the function and assign num if it's undefined, otherwise you overwrite it every time:






    function once(func) {
    let num;

    function retFunc(x) {
    num = (num === undefined) ? func(x) : num
    return num;
    }
    return retFunc;
    }

    function addByTwo(input) {
    return input + 2;
    }

    var onceFunc = once(addByTwo);

    console.log(onceFunc(4)); //should log 6
    console.log(onceFunc(10)); //should log 6
    console.log(onceFunc(9001)); //should log 6





    Note that if the function you pass in returns undefined it will be called more than once. If you need to handle that case you can set a flag to indicate whether the cached value is valid.






    share|improve this answer


























    • wow, you're really helpful around here aren't ya? no wonder you have 36.8k rep

      – Yang K
      Jan 7 at 7:30











    • @YangK mostly insomnia!

      – Mark Meyer
      Jan 7 at 7:31











    • same here but not as smart or helpful as you lol

      – Yang K
      Jan 7 at 7:43














    8












    8








    8







    You should only call the function and assign num if it's undefined, otherwise you overwrite it every time:






    function once(func) {
    let num;

    function retFunc(x) {
    num = (num === undefined) ? func(x) : num
    return num;
    }
    return retFunc;
    }

    function addByTwo(input) {
    return input + 2;
    }

    var onceFunc = once(addByTwo);

    console.log(onceFunc(4)); //should log 6
    console.log(onceFunc(10)); //should log 6
    console.log(onceFunc(9001)); //should log 6





    Note that if the function you pass in returns undefined it will be called more than once. If you need to handle that case you can set a flag to indicate whether the cached value is valid.






    share|improve this answer















    You should only call the function and assign num if it's undefined, otherwise you overwrite it every time:






    function once(func) {
    let num;

    function retFunc(x) {
    num = (num === undefined) ? func(x) : num
    return num;
    }
    return retFunc;
    }

    function addByTwo(input) {
    return input + 2;
    }

    var onceFunc = once(addByTwo);

    console.log(onceFunc(4)); //should log 6
    console.log(onceFunc(10)); //should log 6
    console.log(onceFunc(9001)); //should log 6





    Note that if the function you pass in returns undefined it will be called more than once. If you need to handle that case you can set a flag to indicate whether the cached value is valid.






    function once(func) {
    let num;

    function retFunc(x) {
    num = (num === undefined) ? func(x) : num
    return num;
    }
    return retFunc;
    }

    function addByTwo(input) {
    return input + 2;
    }

    var onceFunc = once(addByTwo);

    console.log(onceFunc(4)); //should log 6
    console.log(onceFunc(10)); //should log 6
    console.log(onceFunc(9001)); //should log 6





    function once(func) {
    let num;

    function retFunc(x) {
    num = (num === undefined) ? func(x) : num
    return num;
    }
    return retFunc;
    }

    function addByTwo(input) {
    return input + 2;
    }

    var onceFunc = once(addByTwo);

    console.log(onceFunc(4)); //should log 6
    console.log(onceFunc(10)); //should log 6
    console.log(onceFunc(9001)); //should log 6






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Jan 7 at 7:37

























    answered Jan 7 at 7:26









    Mark MeyerMark Meyer

    39.7k33262




    39.7k33262













    • wow, you're really helpful around here aren't ya? no wonder you have 36.8k rep

      – Yang K
      Jan 7 at 7:30











    • @YangK mostly insomnia!

      – Mark Meyer
      Jan 7 at 7:31











    • same here but not as smart or helpful as you lol

      – Yang K
      Jan 7 at 7:43



















    • wow, you're really helpful around here aren't ya? no wonder you have 36.8k rep

      – Yang K
      Jan 7 at 7:30











    • @YangK mostly insomnia!

      – Mark Meyer
      Jan 7 at 7:31











    • same here but not as smart or helpful as you lol

      – Yang K
      Jan 7 at 7:43

















    wow, you're really helpful around here aren't ya? no wonder you have 36.8k rep

    – Yang K
    Jan 7 at 7:30





    wow, you're really helpful around here aren't ya? no wonder you have 36.8k rep

    – Yang K
    Jan 7 at 7:30













    @YangK mostly insomnia!

    – Mark Meyer
    Jan 7 at 7:31





    @YangK mostly insomnia!

    – Mark Meyer
    Jan 7 at 7:31













    same here but not as smart or helpful as you lol

    – Yang K
    Jan 7 at 7:43





    same here but not as smart or helpful as you lol

    – Yang K
    Jan 7 at 7:43











    4














    What you're missing is removing the original function after the first execution. You should modify your code in the following way:



    function once(func) {
    let num;
    function retFunc(x){
    if (func)
    num = func(x);
    func = null;
    return num;
    }
    return retFunc;
    }

    function addByTwo(input){
    return input + 2;
    }

    var onceFunc = once(addByTwo);

    console.log(onceFunc(4)); //should log 6
    console.log(onceFunc(10)); //should log 6
    console.log(onceFunc(9001)); //should log 6


    This way you remove the function after first usage and you're just keeping the result.






    share|improve this answer
























    • Also i'd like to say that this way is better than relying on the result, because function doesn't need to always return something. It may return undefined, but we still want to run it only once.

      – tswistak
      Jan 7 at 11:51
















    4














    What you're missing is removing the original function after the first execution. You should modify your code in the following way:



    function once(func) {
    let num;
    function retFunc(x){
    if (func)
    num = func(x);
    func = null;
    return num;
    }
    return retFunc;
    }

    function addByTwo(input){
    return input + 2;
    }

    var onceFunc = once(addByTwo);

    console.log(onceFunc(4)); //should log 6
    console.log(onceFunc(10)); //should log 6
    console.log(onceFunc(9001)); //should log 6


    This way you remove the function after first usage and you're just keeping the result.






    share|improve this answer
























    • Also i'd like to say that this way is better than relying on the result, because function doesn't need to always return something. It may return undefined, but we still want to run it only once.

      – tswistak
      Jan 7 at 11:51














    4












    4








    4







    What you're missing is removing the original function after the first execution. You should modify your code in the following way:



    function once(func) {
    let num;
    function retFunc(x){
    if (func)
    num = func(x);
    func = null;
    return num;
    }
    return retFunc;
    }

    function addByTwo(input){
    return input + 2;
    }

    var onceFunc = once(addByTwo);

    console.log(onceFunc(4)); //should log 6
    console.log(onceFunc(10)); //should log 6
    console.log(onceFunc(9001)); //should log 6


    This way you remove the function after first usage and you're just keeping the result.






    share|improve this answer













    What you're missing is removing the original function after the first execution. You should modify your code in the following way:



    function once(func) {
    let num;
    function retFunc(x){
    if (func)
    num = func(x);
    func = null;
    return num;
    }
    return retFunc;
    }

    function addByTwo(input){
    return input + 2;
    }

    var onceFunc = once(addByTwo);

    console.log(onceFunc(4)); //should log 6
    console.log(onceFunc(10)); //should log 6
    console.log(onceFunc(9001)); //should log 6


    This way you remove the function after first usage and you're just keeping the result.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Jan 7 at 7:28









    tswistaktswistak

    5113




    5113













    • Also i'd like to say that this way is better than relying on the result, because function doesn't need to always return something. It may return undefined, but we still want to run it only once.

      – tswistak
      Jan 7 at 11:51



















    • Also i'd like to say that this way is better than relying on the result, because function doesn't need to always return something. It may return undefined, but we still want to run it only once.

      – tswistak
      Jan 7 at 11:51

















    Also i'd like to say that this way is better than relying on the result, because function doesn't need to always return something. It may return undefined, but we still want to run it only once.

    – tswistak
    Jan 7 at 11:51





    Also i'd like to say that this way is better than relying on the result, because function doesn't need to always return something. It may return undefined, but we still want to run it only once.

    – tswistak
    Jan 7 at 11:51











    3














    This is your problem



    function retFunc(x){
    num = func(x);
    return num;
    }


    You're always calling func(x). Add an if condition to check if num is undefined before calling func(x).






    share|improve this answer
























    • Hi by adding if condition to check whether num is undefined my code is working now.

      – Amit Kumar
      Jan 7 at 7:31


















    3














    This is your problem



    function retFunc(x){
    num = func(x);
    return num;
    }


    You're always calling func(x). Add an if condition to check if num is undefined before calling func(x).






    share|improve this answer
























    • Hi by adding if condition to check whether num is undefined my code is working now.

      – Amit Kumar
      Jan 7 at 7:31
















    3












    3








    3







    This is your problem



    function retFunc(x){
    num = func(x);
    return num;
    }


    You're always calling func(x). Add an if condition to check if num is undefined before calling func(x).






    share|improve this answer













    This is your problem



    function retFunc(x){
    num = func(x);
    return num;
    }


    You're always calling func(x). Add an if condition to check if num is undefined before calling func(x).







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Jan 7 at 7:25









    asleepysamuraiasleepysamurai

    816716




    816716













    • Hi by adding if condition to check whether num is undefined my code is working now.

      – Amit Kumar
      Jan 7 at 7:31





















    • Hi by adding if condition to check whether num is undefined my code is working now.

      – Amit Kumar
      Jan 7 at 7:31



















    Hi by adding if condition to check whether num is undefined my code is working now.

    – Amit Kumar
    Jan 7 at 7:31







    Hi by adding if condition to check whether num is undefined my code is working now.

    – Amit Kumar
    Jan 7 at 7:31













    2














    different approach: overwrite the call to func



    no flags, check if result is undefined or anything required



    function once(func) {
    let num;

    let internalFn = function(x) {
    num = func(x);
    internalFn = function(x) {
    return num;
    }
    return num;
    }

    function retFunc(x){
    return internalFn(x);
    }
    return retFunc;
    }

    function addByTwo(input){
    return input + 2;
    }

    var onceFunc = once(addByTwo);

    console.log(onceFunc(4)); //should log 6
    console.log(onceFunc(10)); //should log 6
    console.log(onceFunc(9001)); //should log 6





    share|improve this answer




























      2














      different approach: overwrite the call to func



      no flags, check if result is undefined or anything required



      function once(func) {
      let num;

      let internalFn = function(x) {
      num = func(x);
      internalFn = function(x) {
      return num;
      }
      return num;
      }

      function retFunc(x){
      return internalFn(x);
      }
      return retFunc;
      }

      function addByTwo(input){
      return input + 2;
      }

      var onceFunc = once(addByTwo);

      console.log(onceFunc(4)); //should log 6
      console.log(onceFunc(10)); //should log 6
      console.log(onceFunc(9001)); //should log 6





      share|improve this answer


























        2












        2








        2







        different approach: overwrite the call to func



        no flags, check if result is undefined or anything required



        function once(func) {
        let num;

        let internalFn = function(x) {
        num = func(x);
        internalFn = function(x) {
        return num;
        }
        return num;
        }

        function retFunc(x){
        return internalFn(x);
        }
        return retFunc;
        }

        function addByTwo(input){
        return input + 2;
        }

        var onceFunc = once(addByTwo);

        console.log(onceFunc(4)); //should log 6
        console.log(onceFunc(10)); //should log 6
        console.log(onceFunc(9001)); //should log 6





        share|improve this answer













        different approach: overwrite the call to func



        no flags, check if result is undefined or anything required



        function once(func) {
        let num;

        let internalFn = function(x) {
        num = func(x);
        internalFn = function(x) {
        return num;
        }
        return num;
        }

        function retFunc(x){
        return internalFn(x);
        }
        return retFunc;
        }

        function addByTwo(input){
        return input + 2;
        }

        var onceFunc = once(addByTwo);

        console.log(onceFunc(4)); //should log 6
        console.log(onceFunc(10)); //should log 6
        console.log(onceFunc(9001)); //should log 6






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Jan 7 at 12:55









        SchreiberLexSchreiberLex

        225120




        225120






























            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%2f54070049%2ffunction-to-cache-its-arguments-return-value%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







            Popular posts from this blog

            Bressuire

            Cabo Verde

            Gyllenstierna