[LeetCode] Allow One Function Call

[LeetCode] Allow One Function Call

PROBLEMS

Description


Given a function fn, return a new function that is identical to the original function except that it ensures fn is called at most once.

  • The first time the returned function is called, it should return the same result as fn.
  • Every subsequent time it is called, it should return undefined.

Example


Example 1:

Input: fn = (a,b,c) => (a + b + c), calls = [[1,2,3],[2,3,6]]
Output: [{“calls”:1,”value”:6}]
Explanation:
const onceFn = once(fn);
onceFn(1, 2, 3); // 6
onceFn(2, 3, 6); // undefined, fn was not called

Example 2:

Input: fn = (a,b,c) => (a * b * c), calls = [[5,7,4],[2,3,6],[4,6,8]]
Output: [{“calls”:1,”value”:140}]
Explanation:
const onceFn = once(fn);
onceFn(5, 7, 4); // 140
onceFn(2, 3, 6); // undefined, fn was not called
onceFn(4, 6, 8); // undefined, fn was not called

Constraints


  • calls is a valid JSON array
  • 1 <= calls.length <= 10
  • 1 <= calls[i].length <= 100
  • 2 <= JSON.stringify(calls).length <= 1000

Solution


  • Runtime: 39ms
  • Memory: 48.32MB
/**
 * @param {Function} fn
 * @return {Function}
 */
var once = function(fn) {
    let isFirstCall = true
    return function(...args) {
        if(isFirstCall) {
            isFirstCall = false
            return fn(...args)
        }
    }
};

/**
 * let fn = (a,b,c) => (a + b + c)
 * let onceFn = once(fn)
 *
 * onceFn(1,2,3); // 6
 * onceFn(2,3,6); // returns undefined without calling fn
 */

Retrospect


문제의 설명은 once라는 함수가 여러번 호출되게 될 경우 처음만 호출되고 나머지 호출이 되지 않아야한다라고 나와있다. 나는 once함수를 제일 처음 생성했을때 isFirstCall라는 변수 명을 하나 같이 선언해주었는데 이렇게 해준 이유는 once함수를 처음 호출했는지 확인하기 위해서이다.

onceFn(1,2,3)을 호출하게 되면 isFirstCall은 true가 되니 조건문 안쪽으로 들어가겠고, 함수에 파라미터를 전달해 원하는 값을 추추할 수 있게 된다. 여기서 이제 isFristCall변수를 false로 바꿔 처음 함수 호출이 끝났다고 알려주면 다음에 호출할때는 onceFn함수가 호출되지 않을꺼고 문제에서 원하는 답을 찾을 수 있게 될 것이다.

onceFn함수 내에서 isFirstCall을 생성하게되면 isFirstCall이라는 변수는 onceFn의 렉시컬 환경에 대한 참조를 저장하게 된다. 안쪽 함수에서는 isFirstCall을 사용할 수 있게 되고 상태가 바뀌게 되면 바뀐 상태 값도 참조할 수 있게 되는 것이다. 만약 안쪽 함수에서 isFirstCall을 선언하고 return 전에 값을 true로 바꾸게 된다면, onceFn 다시 호출될 때 isFirstCall은 초기값인 false로 바껴있을 것이다.

실질적으로 호출되는 부분은 function(..args)인데 해당 함수를 호출하게 되면 렉시컬환경이 계속 새롭게 생성되어질 것이고, 값은 초기화가 될 것이다. 그래서 렉시컬스코프에 의해 상위 스코프에 변수를 선언해서 사용하면 상태 변화를 알 수 있을 것이다.


© 2024. All right reserved Min