reduce!

갈 길 이 먼·2021년 8월 11일
0

codewars

목록 보기
1/2
post-thumbnail

문제 내용 추가: a, b 사이에 조건을 만족하는 숫자가 없다면 빈배열을 리턴해라.

sumDigPow(90, 100) == []

오늘도 난 안전하게 for문을 돌린다...
하지만 난 array.reduce((a, b, c, d) => 어쩌구, i) 이렇게 리듀스 함수의 파라미터를 2개 이상 써서 멋지게 리듀스를 돌리는 사람들을 부러워한다. 나도 알고는 있다.
a = accumulator
b = current value
c = index
d = array
i = initial value

한번 볼까?

아래는 내가 부러워하는 리듀스 잘 쓴 남의 코드다.

function sumDigPow(a, b) {
  var ans = [];
  while(a <= b){
    if(a.toString().split('').reduce((x,y,i)=>x + +y ** (i + 1),0) == a)
      ans.push(a);
    a++;
  }
  return ans;
}

아래는 내가 쓴 코드이다;

function sumDigPow(a, b) {
  let answer = [];
  
  for (let i = a; i <= b; i++) {
    let upTo = String(i).length;
    let sum = 0;
    for (let j = 0; j < upTo; j++) {
      sum += Math.pow(Number(String(i)[j]), j + 1)
    }
    if (sum === i) answer.push(i); 
  }
  return answer
}

지금 보니, 저기 높으신 분은 Number()대신에 +기호로 문자숫자열을 숫자화했다. 나도 알고있었는데, 왜 쓰지 않았을까요. 리듀스 쓰니 sum이란 변수도 필요없고, 1줄에 로직이 끝나버렸다. 오늘도 이렇게 남의 코드를 보고 배웁니다.

연습할 겸 리팩토링한 코드

function sumDigPow(a, b) {
  let answer = [];
  
  while(a <= b) {
    if (String(a).split('').reduce((x, y, i) => x + Math.pow(+y, i + 1), 0) === a) 
      answer.push(a);
    a++;
  }
  return answer
}

리듀스는 배열의 인덱스값도 활용할 수 있어서 for문 대신에 정말 유용하구나. while문에서도 리듀스 쓰면 인덱스 값을 활용할 수가 있겠네. 🧐
❗️주의해야 할 점: if문의 return문인 answer.push(a)를 나와서 a++ 로 증가해야지 그렇지 않으면 콜백지옥에 빠져 시간초과를 면치못한다.

profile
개발자로의 여정

0개의 댓글