Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,21 @@
# javascript-calculator-precourse
# javascript-calculator-precourse

기능목록

1. 문자열 분리 및 합산 기능
- 입력된 문자열에서 숫자를 추출한다.
- 숫자들을 합산하여 반환한다.

2. 커스텀 구분자 처리 기능
- 기본 구분자 외에 커스텀 구분자를 입력받는다. (//과 \n사이에 있으면 커스텀 구분자로 인식)
- 숫자들을 합산하여 반환한다.

3. 잘못된 입력 처리 기능
- 구분자가 두 번 연속으로 들어있는 경우
- 커스텀 구분자 지정이 잘못된 경우
- 구분자와 숫자 사이에 공백이 있는 경우
- 숫자가 아닌 값이 포함된 경우
-> IllegalArgumentException 발생, 애플리케이션 종료

4. 빈 문자열 처리 기능
- 빈 문자열 입력시 0을 반환한다.
55 changes: 53 additions & 2 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,56 @@
import { Console } from "@woowacourse/mission-utils";

class StringCalculator {
static add(numbers) {
const { customDelimiter, input } = this.extractCustomDelimiter(numbers);
const delimiters = [',', ':', customDelimiter].filter(Boolean); // customDelimiter = null이면 delimiters에 포함되지 않음

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

filter(Boolen)을 사용하는 방식도 있네요!
이렇게 작성하면 delimiters에 대입하는 코드 작성 없이
간결하게 쓸 수 있겠네요


let numArray = [input];
for (const delimiter of delimiters) {
let tempArray = [];
for (const number of numArray) {
tempArray = tempArray.concat(number.split(delimiter)); // 구분자로 분리
}
numArray = tempArray;
}

numArray = numArray
.filter(num => num.trim() !== "") // 구분자와 숫자 사이에 공백이 있는 경우 처리
.map(num => {
const numValue = Number(num);
if (isNaN(numValue) || numValue < 0) {
throw new Error ("[ERROR] IllegalArgumentException"); //양수만 입력 가능
}
return numValue;
});

return numArray.reduce((sum, num) => sum + num, 0); // 합산하여 반환, 초기값 0이므로 빈 문자열이 들어가면 0 반환
}

static extractCustomDelimiter(numbers) {
if (numbers.startsWith('//')) { // startsWith : 문자열이 //로 시작하는지 확인
const linebreakIndex = numbers.indexOf('\\n'); // indexOf : 찾은 문자 위치 반환, 찾지 못하면 -1 반환

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저는 input으로 들어오는 \n을 \n으로 replace하는 방식을 사용했는데
이런 식으로 하면 더 간단하게 사용할 수 있겠네요
참고하겠습니다

if (linebreakIndex !== -1) {
const customDelimiter = numbers.slice(2, linebreakIndex); // 구분자가 두 번 연속으로 들어있는 경우 처리

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

혹시 이 부분이 어떤 방식으로 구분자가 두 번 연속으로 들어있는 경우를 처리하는지 알려주실 수 있나요?
코드대로라면 //이후부터 \n직전까지의 모든 부분을 slice하는 것 같은데
그럼 만약 //***\n이면 ***이 모두 포함되는 거 같아서요

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

구분자가 두 번 연속으로 들어있는 경우에 어떻게 처리가 되는 지 설명해주실 수 있나요?

const input = numbers.slice(linebreakIndex + 2); // 커스텀 지정자 뒤부터 자르기
return { customDelimiter, input };
}
}
return {customDelimiter: null, input: numbers }; // 예외처리 : 커스텀이 없는 경우
}
}

class App {
async run() {}
async run() {
try {
const input = await Console.readLineAsync('입력: ');
const result = StringCalculator.add(input);
Console.print(`결과 : ${result}`);
} catch(error) {
Console.print(error.message);
return Promise.reject(error);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

async 함수 내에서 예외가 발생하면 Promise객체는 자동으로 reject상태로 변경되기 때문에
여기서 51행이 불필요한 걸루 알고 있어요!
근데 저도 아직 공부가 부족해서 구체적으로는... 설명하기가 어렵네요
이 부분은 제가 더 공부해서 다시 리뷰 작성하러 오겠습니다

}
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

주석을 상세하게 달아두셔서 코드를 이해하기 쉽습니다. 클래스를 따로 생성하셔서 run()함수를 간결하게 작성하신 것이 인상 깊습니다:)


export default App;
export default App;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

App 클래스만 export 하셨는데 StringCalculator 클래스를 따로 export 하지 않아도 test파일에서 정상적으로 작동하나요?? 작동한다면 왜 그런지...?(순수하게 몰라서 하는 질문입니닷...)