[프로그래머스 | JS] 레벨 0. 세 개의 구분자 (feat. [], {}은 true다)
❓ 문제: 세 개의 구분자
임의의 문자열이 주어졌을 때 문자 "a", "b", "c"를 구분자로 사용해 문자열을 나누고자 합니다.
예를 들어 주어진 문자열이 "baconlettucetomato"라면
나눠진 문자열 목록은 ["onlettu", "etom", "to"] 가 됩니다.
문자열 myStr이 주어졌을 때 위 예시와 같이 "a", "b", "c"를 사용해
나눠진 문자열을 순서대로 저장한 배열을 return 하는 solution 함수를 완성해 주세요.
단, 두 구분자 사이에 다른 문자가 없을 경우에는 아무것도 저장하지 않으며,
return할 배열이 빈 배열이라면 ["EMPTY"]를 return 합니다.
📝 문제 풀이
정규식을 활용해서 해당 구분자(a, b, c)로 문자열을 나누고 배열을 반환하면 되는데
split으로 문자열을 나눈 배열에는 빈 문자열 ""이 포함되어 있어 filter(Boolean) 으로 걸러서 반환하는걸로 생각했다.
function solution(myStr) {
// 제출한 방법
// 문자열이 구분자로만 이루어져 있으면 ["EMPTY"] 반환
// 아니라면 구분자로 구분된 배열 빈 문자열 제외하고 반환
return !myStr.match(/[^abc]/g) ? ["EMPTY"] : myStr.split(/a|b|c/g).filter(Boolean);
// 고민했던 방법
// 빈 배열이면 false값을 반환할거라고 생각했는데 true값이어서 위 방법으로 풀어서 냈다
return myStr.split(/a|b|c/g).filter(Boolean) || ["EMPTY"];
}
고민했던 방법으로 하고 싶었지만 빈 배열과 객체는 true값이기 때문에
아쉽지만 구분자로만 이루어졌는지 확인하고 다시 나누는 작업을 반복하는 방법으로 풀어냈다.
그리고 다른 분들의 풀이를 찾아봤다.
const solution = s => s.match(/[^abc]+/g) || ['EMPTY']
// 정규식에 일치하는 요소들 배열로 반환
// 없으면 null 반환
match를 사용하면 내가 원하는 방향으로 풀 수 있었다니..!
null을 반환하기 때문에 or로 할 수 있으니 훨씬 효율적이고 직관적이다.
물론 속도도 굉장히 빨라진다.
🔍 더 파고들기 - 왜 빈 배열과 빈 객체는 true인가
우선 false값을 살펴보자
- 0
- false
- undefined
- null
- '' 또는 "" (빈 문자열)
- NaN
물론 if ([].length === 0) 로 false값을 도출할 수 있지만
왜 빈 배열과 빈 객체가 ture값인지가 궁금했다.
우선 자바스크립트에서 배열은 객체 타입이고, 객체는 참조형이다.
Boolean값을 평가할 때는 데이터를 강제로 형변환시키는데
객체는 참조값으로 비교되기 때문에 그 안에 데이터가 없어도 truthy한 값으로 평가돼 true를 반환한다.
그럼 왜 참조값은 truthy한 값이냐라고 궁금할 수 있다 (나만 그런가?)
객체 안이 비어있더라도 객체는 주소값을 가리키고 있기 때문이다 (이름도 참조형이지 않은가)
이 주소값은 실제 있는 유효한 값이기 때문에 이를 가리키는, 참조하는 객체도 유효한 값으로 평가된다.
자바스크립트는 알면 알수록 허점(?)이 많아서 어렵다가도 그 점을 이용하는 맛이 있는 것 같다.
내용에 오류가 있다면 언제든 말씀주세요 :-)
모두 즐코하세요-!