ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • map(parseInt) 가 NaN 으로 응답했을 때, 이 문제는 모종의 유적(類的) 문제틀로 인한 파생이 아닐까 하는...
    JavaScript/입 속의 검은 잎 2022. 9. 26. 20:42

     

    https://medium.com/dailyjs/parseint-mystery-7c4368ef7b21

     

     

    Why ['1', '7', '11'].map(parseInt) returns [1, NaN, 3] in Javascript

    Javascript is weird.

    medium.com


    23번 문제 "자연수 뒤집기" 에서 나온 이슈

     

    let n = 12345 // 임의로 넣은 수
    
    function solution(n) {
        const arr = (n + '').split('') // 숫자->문자->배열
        console.log(arr) // [ '1', '2', '3', '4', '5' ]
        
        const arr2 = arr.map(parseInt);
        console.log(arr2) // [ 1, NaN, NaN, NaN, NaN ]
        
        const arr3 = arr.map(value => parseInt(value))
        console.log(arr3) // [ 1, 2, 3, 4, 5 ]
        return arr3.sort((a,b)=>b-a)
    
    }
    
    console.log(solution(n)) // [ 5, 4, 3, 2, 1 ]

     

    arr2는 얼마나 쓰라린 결과였는가.

    배열  [ '1', '2', '3', '4', '5' ]에 map(parseInt)라는 명령을 내렸을 때, [ 1, NaN, NaN, NaN, NaN ]이 반환된다.

    무슨 일이 일어났는가?

    일단 상식하나. 
    All values are truthy except for: false, 0, "" (empty string), null, undefined, and NaN.
    false, 0, "", null, undefined, NaN 말고는 트루.

    문자열 'false'도, 문자열 '0'도, 빈 객체{}도, 빈 배열[]도, 트루.
    외우자, 펄스영공백눌언난... 펄스영공백눌언난...

     

     

    아래는 mdn 문서의 구문이다.

    arr.map(callback(currentValue[, index[, array]])[, thisArg])

    그리고 요소 하나하나에서 map이 무슨 변화를 가져오는지 콘솔에 찍어보자.

    주지하듯이, map은 앞의 array의 각 요소들을 모두 돌며 자신의 구문을 콘솔에 찍을 거다.

    [1, 2, 3, 4, 5].map(console.log);

     

    각각 돌면서 착하게 value만 찍어줄 줄 알았지?

    map()이 그 정도였으면 이리 활용도 높은 메서드일리가 없다.

    value - index - fullarray 까지 다 찍혀있다.

     

    [1, 2, 3, 4, 5].map(console.log);
    // The above is equivalent to
    [1, 2, 3, 4, 5].map(
        (val, index, array) => console.log(val, index, array)
    );
    // and not equivalent to
    [1, 2, 3, 4, 5].map(
        val => console.log(val)
    );

    map() 안에 다른 함수가 들어올 때, 각각의 반복을 돌며 세 개의 인수가 함수를 스치운다.

    value, index, full array.

     

    그런데 ParseInt는? 

    주지하듯이 ParseInt는 두가지 인수를 받는다. 

    문자열(string)과 기수법(radix). 

     

    하지만 배열  [ '1', '2', '3', '4', '5' ]에 map(parseInt)라는 명령을 내렸을 때, map()은 parseInt에게...

    요소를 돌며 각각 value1,2,3,4,5 와 그 index인 0,1,2,3,4와 배열전체를 때려박는다.

    그리고 parseInt는 이렇게 받아들인다.

    value 1이 0진법, value 2가 1진법으로 들어온다고.

     

    3,4,5가 2진법, 3진법, 4진법으로 들어와서 NaN이 찍힌 것도 아니다. 

    parse Int 는 두개의 인수만 받기에, 나머지는 쓰레기통으로 간다.

    딸려온 full array 도 마찬가지. 

    이 쓰레기통에 대해서는 유사 배열 객체에서 알아보자.

     

    하여튼 parseInt는 대충 아래와 같이 돌아간다.
    parseInt('11');                => 11
    parseInt('11', 2);             => 3
    parseInt('11', 16);            => 17
    parseInt('11', undefined);     => 11 (radix is falsy) // 기수법에서 false는 10진법으로 default.
    parseInt('11', 0);             => 11 (radix is falsy) // 기수법에서 false는 10진법으로 default.
    undefined나 0은 10진법으로 지정해준다.

    배열  [ '1', '2', '3', '4', '5' ]에 map(parseInt)라는 명령을 내렸을 때, 

    parseInt는 0진법(을 10진법으로 그냥 읽어준다) 숫자 1, 1진법 숫자2 를 받은 셈이다.

    그리고 [ 1, NaN, NaN, NaN, NaN ]이 반환된다.

     


    데이터 형태를 조물락 거리는 일에 왜 내 취향이 기울어져 있는지는 더 두고보아야 알 일이다.

    하여튼 그래서, map()에는 세가지 인수가, parseInt에는 2가지 인수가 스치운다.

    혹은 매개변수라고 하든가.

     

Designed by Tistory.