문제

Write a generator function that returns a generator object which yields the fibonacci sequence.

The fibonacci sequence is defined by the relation Xn = Xn-1 + Xn-2.

The first few numbers of the series are 0, 1, 1, 2, 3, 5, 8, 13.

https://leetcode.com/problems/generate-fibonacci-sequence/

 

예시

fibonacci sequence를 수행하는 generator 함수를 짜면 된다.

 

코드

/**
 * @return {Generator<number>}
 */
var fibGenerator = function*() {
    let n_2 = 0;
    let n_1 = 1;
    
    for(let i = 0; i <= 50; i++){
        yield n_2;
        
        [n_2, n_1] = [n_1, n_2 + n_1];
            
    }
};

/**
 * const gen = fibGenerator();
 * gen.next().value; // 0
 * gen.next().value; // 1
 */

n-2 를 담을 변수와 n-1을 담을 변수를 만들고, for문을 돌며 값을 넣고 next() 호출 시 n-2 가 나오도록 하였다.

generator 함수

💡 정의 및 특징

  • iterator 객체를 반환하는 함수
    • Generator 객체임
  • function* 는 해당 함수가 generator 함수라는 의미이다.
    • * 은 애스터리스크라고 부른다
  • 빠져나갔다가 원할 때 다시 돌아올 수 있는 함수
    • 변수 값(컨텍스트)가 출입 과정에서 저장된 상태로 남아있음

💡 동작 방식

  • generator 함수는 호출되면 Iterator 객체가 반환됨
    • 즉시 실행 x
  • Iterator의 next() 메서드 호출 시, 함수가 실행됨
  • yield 문을 만날 때까지 진행하다가 만나면 yield표현식이 명시하는 Iterator부터의 반환 값을 리턴
    • 반환 값 형태
      • {value : “”, done: “”}
      • value : yield 문이 반환할 값을 나타내는 속성
      • done : yield 문의 실행 여부를 표시하는 boolean 타입의 값
  • 그 후 next() 메서드가 다시 호출되면, 진행이 멈췄던 위치에서 다시 재실행
  • next(인자값)으로 호출하면 진행을 멈췄던 위치의 yield 문을 next() 메서드에 들어온 인자값으로 치환하고 그 위치에서 다시 실행
  • yield* 표현식을 만나면 다른 Generator함수가 위임 되어서 진행됨.

💡 문법

function* name([param[, param[, ... param]]]) {
       statements
}
  • name : 함수명
  • param : 함수에 전달되는 인수의 이름
  • statements : 구문들

💡 인스턴스 메서드

  • Generator.prototype.next()
    • yield 된 값을 반환함
  • Generator.prototype.return()
    • 주어진 값을 반환 후, generator 종료
  • Generator.prototype.throw()
    • generator에 오류 발생 시킴.

 

참고 사이트

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/function*

 

function* - JavaScript | MDN

function* 선언 (끝에 별표가 있는 function keyword) 은 generator function 을 정의하는데, 이 함수는 Generator 객체를 반환합니다.

developer.mozilla.org

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Generator

 

Generator - JavaScript | MDN

Generator 객체는 generator function 으로부터 반환되며, 반복 가능한 프로토콜과 반복자 프로토콜을 모두 준수합니다.

developer.mozilla.org

 

728x90

문제

Given an integer array arr and a mapping function fn, return a new array with a transformation applied to each element.

The returned array should be created such that returnedArray[i] = fn(arr[i], i).

Please solve it without the built-in Array.map method.

https://leetcode.com/problems/apply-transform-over-each-element-in-array/

 

예시

직접 map 함수를 구현하면 된다. arr에 있는 각 원소에 fn을 적용하여 다시 넣어주면 된다.

 

코드

/**
 * @param {number[]} arr
 * @param {Function} fn
 * @return {number[]}
 */
var map = function(arr, fn) {
    let newArr = [];
    
    arr.forEach((number, idx)=>{
        newArr.push(fn(number, idx));
    });
    
    return newArr;
};

리턴할 새로운 배열인 newArr를 만들고, arr를 돌면서 fn의 인자로 넣어준 뒤, 해당 결과를 newArr에 push 해주었다.

728x90

문제

Given an integer array arr and a filtering function fn, return a filtered array filteredArr.

The fn function takes one or two arguments:

  • arr[i] - number from the arr
  • i - index of arr[i]

filteredArr should only contain the elements from the arr for which the expression fn(arr[i], i) evaluates to a truthy value. A truthy value is a value where Boolean(value) returns true.

Please solve it without the built-in Array.filter method.

https://leetcode.com/problems/filter-elements-from-array/

 

예시

직접 filter 함수를 구현하면 된다. array를 돌면서 fn의 함수에 true가 나오는 값만 얕은 복사하여 새로운 배열을 만들어 준다.

 

코드

type Fn = (n: number, i: number) => any

function filter(arr: number[], fn: Fn): number[] {
    let newArr = [];
    
    arr.forEach((number, idx)=>{
        if(fn(number, idx)){
            newArr.push(number);
        }
    });
    
    return newArr;
};

리턴할 새로운 배열인 newArr를 만들고, arr를 돌면서 fn의 결과가 true인 원소만 newArr에 추가해주었다.

728x90

문제

Given an array of functions [f1, f2, f3, ..., fn], return a new function fn that is the function composition of the array of functions.

The function composition of [f(x), g(x), h(x)] is fn(x) = f(g(h(x))).

The function composition of an empty list of functions is the identity function f(x) = x.

You may assume each function in the array accepts one integer as input and returns one integer as output.

https://leetcode.com/problems/function-composition/

 

예시

functions에 있는 각 함수들을 뒤에서부터 실행하면 된다. 주어진 x 값을 이용하여 x의 값을 업데이트한다.

 

코드

/**
 * @param {Function[]} functions
 * @return {Function}
 */

Array.prototype.myReverse = function(){
    return this.map((item,idx) => this[this.length-1-idx]);
}

var compose = function(functions) {
    
    return function(x) {
        let value = x;
        
        functions.myReverse().forEach((fn)=>{
            value = fn(value);
        });
        
        return value;
    }
};

/**
 * const fn = compose([x => x + 1, x => 2 * x])
 * fn(4) // 9
 */

 

함수 배열의 순서를 바꾼 뒤, 바뀐 함수 배열을 돌면서 value 값을 업데이트 했다.

Array.prototype.reverse()가 존재하지만, 직접 구현해보고 싶었다. (추가적으로, reverse()가 좀 느리지 않을까라는 생각이 들었다. 관련해서는 참고 링크를 보면 좋을 것 같다.)

 

 

참고 링크

https://medium.com/@toaonly42/array-prototype-reverse-%EA%B0%80-%EC%B5%9C%EC%84%A0%EC%9D%B8%EA%B0%80-5acb17e315d3

 

Array.prototype.reverse 가 최선인가?

🤔 뜬금없는 의문,

medium.com

https://gurtn.tistory.com/121

 

[JS] 반복문 (for, forEach 등) 속도 비교

JavaScript의 반복문으로 for loop 문, forEach 메서드, map 메서드, reduce 메서드, $.each (Jquery) 등 정말 많은 종류의 반복문이 존재합니다. 비교 해볼 반복문 for loop forEach map reduce $.each 속도 비교에 사용할

gurtn.tistory.com

 

728x90

문제

Given an integer array nums, a reducer function fn, and an initial value init, return the final result obtained by executing the fn function on each element of the array, sequentially, passing in the return value from the calculation on the preceding element.

This result is achieved through the following operations: val = fn(init, nums[0]), val = fn(val, nums[1]), val = fn(val, nums[2]), ... until every element in the array has been processed. The ultimate value of val is then returned.

If the length of the array is 0, the function should return init.

Please solve it without using the built-in Array.reduce method.

https://leetcode.com/problems/array-reduce-transformation/

 

예시

input으로 nums 배열과 reduce로 실행할 함수, 그리고 초기 값을 받는다. accum은 fn에서 리턴한 값이 들어가고, curr은 nums 배열에 있는 숫자가 들어간다.

 

코드

/**
 * @param {number[]} nums
 * @param {Function} fn
 * @param {number} init
 * @return {number}
 */
var reduce = function(nums, fn, init) {
    if(nums.length === 0) return init;
    
    let accum = init;
    nums.forEach((num)=>{
        accum = fn(accum, num);
    });
    
    return accum;
};

문제에 적혀있는 대로, nums 배열의 길이가 0이면 초기 값을 리턴한다.

fn(accum, curr)에서 accum은 앞선 실행됐던 fn의 결과 값이고, curr은 현재 nums 배열에 있는 숫자이다. for문을 돌면서 nums에서 각 숫자가 fn의 curr로 들어갈 수 있도록 하였고, fn의 결과를 accum 변수에 저장해주었다.

728x90

+ Recent posts