문제 : 대문자와 소문자가 섞여있는 문자열 s가 주어집니다. s에 'p'의 개수와 'y'의 개수를 비교해 같으면 True, 다르면 False를 return 하는 solution를 완성하세요. 'p', 'y' 모두 하나도 없는 경우는 항상 True를 리턴합니다. 단, 개수를 비교할 때 대문자와 소문자는 구별하지 않습니다.

https://school.programmers.co.kr/learn/courses/30/lessons/12916

 

프로그래머스

SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr


코드 1

function solution(s){
    let a = [...s].reduce((acc, num) => {
        return (num == 'p' || num == 'P') ? acc + 1 : acc;
    }, 0);
    let b = [...s].reduce((acc, num) => {
        return (num == 'y' || num == 'Y') ? acc + 1 : acc;
    }, 0);
    return a === b ? true : false;
}

 

 

  • 문자열을 스프레드 연산자로 하나씩 분리한 뒤 reduce 로 순회했다.
  • 대소문자 비교를 위해 'p' / 'P', 'y' / 'Y' 를 모두 조건에 넣고 누적값을 증가시켰다.
  • 마지막에 p와 y의 개수를 비교하여 true / false를 반환했다.

 

전체적인 로직은 잘 동작한다👍


처음에 작성한 틀린 코드

function solution(s){
    let a = [...s].reduce((acc, num) => {
        (num == 'p' || num == 'P') ? acc + 1 : acc; // return을 하지 않음
    }, 0);
    let b = [...s].reduce((acc, num) => {
        (num == 'y' || num == 'Y') ? acc + 1 : acc; // return을 하지 않음
    }, 0);
    return a == b ? true : false;
}

 

‼️ 문제가 생긴 이유 -> 이 코드는 어떤 입력을 넣어도 무조건 true를 반환하였다.

 

무조건 true를 반환한 이유 : reduce 콜백 안에서 return 을 하지않았기 때문에 삼항 연산자로 계산을 하였으나 그 값을 반환하지 않아서 콜백이 항상 undefined 를 반환한다. undefined == undefined 에서 무조건 true 가 나오는 이유가 이런 이유 때문이였다.

 

 

이 실수 덕분에 reduce 가 어떻게 작동하는지 한 번 더 확실하게 알게되었다 😊


코드2 (흥미로웠던 코드)

function solution(s){
    let lower = s.toLowerCase().split('');
    return lower.filter(c => c === 'p').length === lower.filter(c => c === 'y').length;
}

 

처음에 문자열 전체를 소문자로 바꿔버리면 대문자 처리를 신경 쓸 필요가 없고, filter로 원하는 문자만 추출하고 길이를 비교하면 끝인 직관적이도 짧은 코드가 흥미로웠다.


< 이번 문제에서 배운 점 >

1. 대소문자 비교는 문자열 통째로 변환하면 훨씬 단순해진다. 

- 처음부터 toLowerCase() 또는 toUpperCase()를 쓰면 조건문에 'p' || 'P' 이렇게 두 번 적을 필요가 없다.

 

2. reduce 는 순회 + 누적을 동시에 하는 메서드이다.

reduce((acc, num) => acc + num, 0)
  • acc -> 누적 값
  • num -> 현재 요소
  • 0 -> 초기 값
  • 리턴값이 다음 acc가 된다. 

 

+ Recent posts