[javascript] arr.slice() 함수 질문

조회수 1066회

안녕하세요. 아래의 그림처럼 배열을 90도 회전하여 출력하는 함수를 만들고자 합니다. 이미지

function rotateImage(a) {
 var b = a.slice()
 // var b = [[1,2,3],[4,5,6],[7,8,9]];

 function arcmove(r,c){
  // console.log(a[r][c])
   b[c][a.length-1-r] = a[r][c]
 }

 for(let i =0 ; i<a.length; i++){
  for(let j =0 ; j<a.length; j++){
    arcmove(i,j)
  }
 }


}

저는 b라는 배열을 만들어 a의 배열에 들어있는 값을 복사한뒤에 arcmove로 a[r][c]의 값을 이동될 좌표로 넣어주었는데요.

var b = [[1,2,3],[4,5,6],[7,8,9]]로 선언했을때는 제가 원하는 90도가 회전되어 잘 출력하는데.. var b = a.slice() 로 선언시에는 [ [ 7, 4, 1 ], [ 2, 5, 2 ], [ 1, 2, 1 ] ] 과 같은 값이 나옵니다.

var b = a 로 가져오는경우 a의 배열이 변경되었을때 b도 수정되는것으로 알고있습니다. 하지만 b = a.slice()로 가져올때는 b는 a와 다른배열이지 않나요?

질문1 왜 var b = a.slice()로 선언한 경우 잘못된 값을 출력하는지 궁금합니다.

질문2 arcmove 함수안에서 a[r][c]를 출력해보았습니다. 그런데 .. 저는 단지b[c][a.length-1-r]a[r][c]값을 넣어주었을 뿐인데 배열 a의 값이 바뀌는것을 보았습니다. 왜 .. 배열 a의 값이 바뀌는것인가요?

질문 읽어주셔서 감사합니다!

  • (•́ ✖ •̀)
    알 수 없는 사용자

1 답변

  • var b = a.slice() 로 얕은 복사를 할 경우 b는 a 객체의 레퍼런스를 참조합니다. a 객체의 레퍼런스를 참조한다는 뜻은 a.slice()와 a는 다른 메모리에 저장되지만, a.slice()안의 b[0][0]과 a안의 a[0][0]의 주소는 동일한곳을 가리킨다는 뜻이지요.

    console.log(b[c][a.length-1-r] === a[c][a.length-1-r] )는 모두 true를 리턴합니다.

    b[c][a.length-1-r] = a[r][c] 에서 b[c][a.length-1-r]a[c][a.length-1-r] 과 같은 곳을 참조합니다. 따라서 b[c][a.length-1-r] 가 바뀌면 a[c][a.length-1-r] 도 바뀌게 됩니다.

    따라서 이 문제를 풀기위해서는 deepcopy로 a 배열을 복사하거나, 빈 배열을 생성해야 합니다.

    혹시 같이 고민해주셨던 분이 계실까 싶어 제가 이해한 풀이를 공유합니다. 혹시 제 답변에 틀린부분이 있다면 답글달아주시면 감사할것같습니다!

    • (•́ ✖ •̀)
      알 수 없는 사용자
    • 1차원 배열(객체안 값)은 그냥 복사가 되지만, 2차원 배열(객체안 객체)은 얕은 복사가 되는거네요..! 저도 덕분에 잘 배웠습니다! 최진우 2019.3.5 11:41
    • 직렬화 가능한 다중 배열이라면 deepcopy에는 역시 JSON.parse(JSON.stringify(a)); 가 최고죠 ㅋㅋ doodoji 2019.3.5 14:11
    • 에고.. 같이 고민해주셔서 제가 더 감사합니다 ㅠㅠ 알 수 없는 사용자 2019.3.5 15:27

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)