아래 코드를 작성하는데, 배열이 계속 변경되어서 애를 먹었다. 또한, 비교도 잘 되지 않았다.
알고보니 forEach,비교 연산자, map()메서드 등 자바스크립트의 기본 원리를 숙지하지 못해서 발생한 문제인 것.
문제
https://school.programmers.co.kr/learn/courses/30/lessons/181881
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
기존 코드
function solution(arr) {
function transfer_arr(lst){
lst.forEach((element,index)=>{
if(element >= 50 && element%2 === 0){
lst[index] = element/2
}
else if(element < 50 && element%2 !==0){
lst[index] = 2*element + 1
}
})
return lst
}
var answer = 0;
let arr_copy = [...arr] //배열을 복사
while (true){
let new_arr = transfer_arr(arr_copy)
if (arr_copy === new_arr){
return answer;
}
else
{
answer+=1
arr_copy = [...new_arr];
}
}
return answer;
}
문제가 발생하는 부분 1. if (arr_copy === new_arr)
- JavaScript에서 배열을 === 연산자로 비교할 때는 두 배열이 정확히 같은 참조를 가리키는지를 비교하게 된다
- 그러나, 내가 하려는 건 두 배열의 '내용' 이 동일한지를 비교하는 것!
- 해결 방법
- === 대신에 JSON.stringify()를 사용하기
- JSON.stringify()는 객체나 배열의 내용을 문자열로 변환하여 비교할 수 있다.
- 수정된 내용
- if (JSON.stringify(arr_copy) === JSON.stringify(new_arr))
문제가 발생하는 부분 2. forEach() 매서드
- forEach() 메서드는 원본 배열을 직접 변경하기 때문에 transfer_arr() 함수가 호출될 때마다 원본 배열이 변경되고, 이는 예상치 못한 결과를 초래할 수 있음!
- forEach()에서 배열의 변경을 가할 때, 원본배열이 변경되므로 비교연산을 진행하는 시점에서는 굉장히 치명적인 로직인 것
- 해결 방법
- map() 메서드를 사용하여 새로운 배열을 생성하고 반환하는 방식으로 수정
수정된 코드
function solution(arr) {
function transfer_arr(lst) {
return lst.map(element => {
if (element >= 50 && element % 2 === 0) {
return element / 2;
} else if (element < 50 && element % 2 !== 0) {
return 2 * element + 1;
} else {
return element; // 변환할 필요가 없는 경우
}
});
}
var answer = 0;
let arr_copy = [...arr] //배열을 복사
while (true){
let new_arr = transfer_arr(arr_copy)
if (JSON.stringify(arr_copy) === JSON.stringify(new_arr)) {
return answer;
}
else
{
answer+=1
arr_copy = [...new_arr];
}
}
return answer;
}