카테고리 없음

15.소수점 처리/ 스프레드 문법/.reduce() 함수

에밀오구 2023. 3. 4. 12:52

🚩부트캠프를 통해 얻고 싶은 나의 목표.

- 하루 평균 3시간 자기주도학습능력(몰입의 경험) -> 블로그 작성/ 플래너 작성   

=> TODAY SCORE: 80점 후하다 후해

-앤트리 개발자 수준의 프론트 개발 실력 쌓기 -> 부트캠프 과제 기한 밀리지 않기!!!(매우 중요)

=> TODAY SCORE: ? 

- 주니어 개발자 수준의 협업능력과 커뮤니케이션 능력 -> 스터디 클럽 운영

 => TODAY SCORE:  ?

- 자바스크립트 딥다이브 책 정독 1회 -> 적극적인 스터디 활동

 => TODAY SCORE:  오늘은 조금 봤으니 50점!

🙇‍♀️오늘을 돌아보며

keep 유지해야할 것

-어떤 부분에 대해 모르는 지 정확히 파악하고 이를 블로그에 꼼꼼하게 작성한 것.

- 공부하다가 더 깊게 드는 의문을 바로 찾거나 빠져들지 않고 의문을  블로그에 작성하고 

 오늘 해야하는 공부 주제로 빠르게 재탐색한 것  너무 칭찬해!🤸‍♀️

- 이전 주를 복습하는 시간을 가진 것. 

-주말에도 공부하는 시간을 가진 것.

- 쉴 공간과 공부할 곳을 분리했다는 점. 집-> 도서관으로 변경 (주말과 평일 저녁) 너무 칭찬해!🤸‍♀️

problem 고쳐야할 것 :  오전에 일찍 일어났지만 밍기적거려서 결국 12시이후에 공부시작한 것 

Try 시도해야할 것:

1.   눈 떠지면 바로 침대에서 내려오기 -> 몸 불편한 상태 만들기 


🏃‍♀️성장한 부분 -📚지식

1. 소수점 버림, 올림, 반올림:

Math.ceil() Math.floor() Math.round() toFixed() toPrecision()

오늘의 프로그래머스 문제는 소수점을 1자리까지는 남겨두고 풀어야하는 문제였습니다. 하지만 버림함수는 Math.floor(숫자)인 것은 알았으나 소수점 반올림 math.round가 기억에 나지 않는데요. 그리고 원하는 소숫점까지  나타내려면 어떻게 코드를 작성하는 지 도 구체적으로 생각나지 않았습니다.  더 나아가 올림은 어떤 함수를 쓰는지도 기억에 나지 않았는데요. 이 지점에서 소수점에 대해 공부가 부족했다 판단했고 이참에 확실히 정리하고 기억하는 시간이되어야 겠다. 판단했습니다.

1.1 Math.ceil() 올림

Math.ceil(매개변수parameter)

*parameter: 올림하고 싶은 숫자

const ceil1 = Math.ceil(1); //1
const ceil1 = Math.ceil(null); //0
const ceil1 = Math.ceil(0); //0
const ceil1 = Math.ceil(-1.111); //-1

//자리수 지정 
const ceil_1 = Math.ceil(1.222 * 10) / 10; // 1.3

//자연수를 소수점 1자리 까지 나타내기는 할 수 없습니다.
const round= Math.ceil(1* 10) / 10; //1일때 1.0으로 나타내고 싶다.
console.log(round); //하지만 결과는 1이 나옵니다.

Math.floor() Math.round() 도 이와 같은 방식으로 진행됩니다. 하지만 원본 숫자의 소수점이하 길이가 유효 소숫점 자리수보다 짧을 때는 표현할 수 없습니다.  그리고  소수점 이하의 값을 올림, 내림, 반올림 처리할 때 부동 소수점의 정밀도 문제 때문에 예상치 못한 결과가 나오기도 하는 데요.  Q. 부동소수점이란 뭘까요? 그리고  Q 왜 예상치못한 결과가 나오기도 할까요? (답변대기중)그래서 이를 해결하기위해선 소수점 반올림 함수 toFixed()와 toPrecision()을 사용해야 합니다. 

1.2 toFixed() 반올림

num.toFixed([digits])

*num: 반올림 싶은 숫자

digits : 유효 소수점 자릿수

const fixed1 = 1.222.toFixed(1); //1.2
const fixed2 = (-1.222).toFixed(1) //-1.2

toFixed()함수는, 부동소수점 숫자를 고정소수점숫자로 바꾸어 리턴합니다.  Q 부동 소수점이란? Q 고정소수점 이란? (답변대기중) 원본 숫자의 소수점이하 길이가 "digits"보다 길면 숫자를 반올림하고 짧으면 뒤를 0으로 채워 리턴합니다.

1.3 toPrecision() 반올림

num.toPrecision([precision])

*num: 반올림 싶은 숫자

precision : 유효 자릿수

toPrecision()함수는 toFIxed와 동일하게 원본숫자길이가 함수 매개변수parameter에 넣은 수, 유효자리숫자보다 짧을 경우 뒤에 0으로 채워 리턴합니다. 하지만 주의할 점이 있습니다. toFixed와 달리 함수의 매개변수parameter에 넣은 수는  유효소수점자릿수가 아닌 유효 자릿수입니다. 그리고  문자열로 리턴합니다. 

const precision1 = 1.222.toPrecision(2); //1.2 
const precision2 = 12.222.toPrecision(2); //12
const precision3 = 12.222.toPrecision(3); //12.2
const precision4 = (123).toPrecision(4); //123.0
console.log(precision1);
console.log(precision2);
console.log(precision3);
console.log(precision4);
console.log(typeof precision1); //string

2. spread 문법

배열의 평균값을 리턴하는 문제에서 spread를 사용했더니 syntaxError 구문 오류가 발생했습니다.   4번줄에서 오류가 발생했고, 예기치 않은 토큰 "..."이라고 나옵니다. Q 토큰은 뭘까요?  (답변 대기중) 아마도 spread 를 잘못 작성한 것같다는 생각을 했습니다.  그래서 spread 문법에 대해  정확히 알아보는 시간을 가졌습니다.

프로그래머스 배열의 평균값 문제

* 해당 프로그래머스 문제: https://school.programmers.co.kr/learn/courses/30/lessons/120817

2.1 스프레드 문법 ...

myFunction(...iterable);
let objClone = { ...iterable};

스프레드 문법은 하나로 뭉쳐있는 여러개의 집합을 펼칩니다. 단 대상은 for of문을 순회하는 이터러블입니다.  Q.  이터러블이 뭘까요?  (답변 대기 중) 그래서 이터러블이 아닌 일반 객체는 스프레드 문법의 대상이 될 수 없습니다.  하지만! 객체 리터럴 내부에서는 스프레드 문법을 사용할 수 있도록 예외처리를 했습니다. (주의하세요! 저는 헷갈렸으니까요!)

-모자딥다634pg

스프레드 문법 사용가능 대상 

  • array
  • string 
  • map Q. map은 타입이 아니라서 대상이 될 수 없지 않나요?  (답변 대기중)
  • set  Q. set은 뭔가요?  (답변대기중)
  • DOM컬렉션 (NodeList, HTMLCollection)  Q. DOM 컬렉션은 뭔가요? (답변대기중)

스프레드 문법의 특징

  • 원본 유지
  • 안에 있는 요소의 type에 따라 그대로 반환
  • 요소를 한 번에 펼칩니다.  하나하나씩 배열의 요소가 들어가는 게 x
  • 스프레드 문법의 결과는 변수에 할당 x (스프레드 문법의 결과는 값이 아니라 값들의 목록이기 때문입니다.)
function sum(x, y, z) {
    return `${x} ${y} ${z}`;
  }
  
  const numbers = [1, 2, 3];
  const prac = "abc";
  const obj = {
    "A":1, 
    "B":2, 
    "C":3
    };
  let newobj ={ ...obj, d:3,f:4}; // 조심! 객체 리터럴안에 쓸때는 예외처리

  console.log(sum(...numbers)); //6 
  console.log(sum(...prac)); //abc 
  //문자열도 오류가 발생하지 않는다.
  
  console.log(newobj); //{ A: 1, B: 2, C: 3, d: 3, f: 4 } 
  //객체에 객체를 넣을 때 오류가 발생하지 않는다. 
  
  console.log(obj); //원본 유지0 
  
  console.log(sum(...obj)); //오류 발생
  // typeError 가 뜬다. non-callable iterator 반복자 호출 불가 
 //반복자(iterator)는 배열이나 그와 유사한 자료 구조의 내부의 요소를 순회(traversing)하는 객체

Q. rest문법과 spread 파라미터는 어떻게 구별할 수 있을까요? 

   spread 문법은 아래와 같은 문맥에서만 사용할 수 있습니다.  

  1. 함수 호출문의 인수 목록
  2. 배열 리터럴의 요소 목록 
  3. 객체 리터럴의 프로퍼티 목록 

2.2 문제의 오류 원인

동기님(김민재님)께 이 문제를 여쭤보니 spread 는 안에 있는 배열요소의 type에 따라 그대로 반환되는건 맞지만 .map()함수처럼 하나하나씩 배열의 요소가 들어가는 게 아니라 요소를 한 번에 넣는 거랑 다름이 없다는 답변을 해주셨습니다.  또한 spread의 주 목적메모리 주소를 바꿔서 원본 값을 수정하는 걸 원치 않을 대 주로 사용된다는 추가적인 답변도 주셨습니다.  

 

이전 잘못된 풀이

function solution(numbers) {
    var answer = 0;
    //배열 number의 요소를 전부 합하고 number의 길이 로 나누기 
    //number배열이 [1,2,3,4]일 경우 
    //spread를 쓰면 answer = 1,2,3,4 /4; 형식이 되버립니다.
    answer= (...numbers) /numbers.length; //오류발생
   
    
   console.log(answer.toFixed(1));
    return answer.toFixed(1);
}
✅해결한 풀이 
function solution(numbers) {
    var answer = 0;
    //전부 합하고 number의 길이 로 나누기 
    numbers.map(x=> answer+=x);
    answer= answer/numbers.length;
    
    return answer.toFixed(1);
}

🏃‍♀️다른분의 풀이  -유길종님

function solution(numbers) {
    var answer = numbers.reduce((a,b) => a+b, 0) / numbers.length;
    return answer;
}

Q reduce는 어떻게 써야하는 지 알아보자!

 


🏃‍♀️더 나아가기

3. Array.reduce()

   .reduce()함수는 배열의 누적값을 리턴해주는 함수입니다.  원본을 훼손하지 않으며 하나의 결과값을 반환합니다. 초기값을 적어주지 않으면 자동으로 0번째 인덱스의 요소가 들어가지만 빈배열일 경우 오류가 날 수 있습니다. 따라서 초기값을 설정하는 것을 추천합니다.  비슷한 함수로 .reduceRight()가 있으며 reduce와 동작은 같지만 요소 순회를 오른쪽에서부터 왼쪽으로 한다는 점이 다른 점입니다.  그리고 reduce 함수 사용시 주의할 점은 return 문을 만나면 화살표 함수를 빠져나가는 것이 아니라  이전에 반환한 값이 acc로 들어가며 계속 reduce함수가 진행된다는 점입니다.  

arr.reduce((acc,cur,idx,src )=>{}, initialValue)

*arr  배열

*acc  누적값

*cur 현잿값

*idx 현재 인덱스

*src 원본 배열

*initialValue 초기값

  const oneTwoThree = [1, 2, 3];
  
  result = oneTwoThree.reduceRight((acc, cur, i) => {
    console.log(acc, cur, i);
    return acc + cur; //반환한 값이 acc 로 들어가며 배열의 마지막 요소까지 reduce함수가 돌아갑니다.
  }, 0); // 초기값을 안주면 빈배열이 들어올 경우 오류가 납니다.
  //누적값 현재요소 현재인덱스
  // 0 3 2
  // 3 2 1
  // 5 1 0
  //result; // 6



  console.log(oneTwoThree); //[1,2,3] 원본을 훼손하지 않습니다.

https://www.youtube.com/watch?v=-GsrYvZoAdA 

https://www.youtube.com/shorts/-IaxGpLCxic?feature=share