230208 JS Array method(splice, slice, concat) 정리 & CyclicRotation

샨티(shanti)·2023년 2월 7일
0

TIL

목록 보기
141/145

매일 매일 하루 한 문제씩.
꾸준히 이어가는 코딩테스트 풀이 기록 ✅

문제 난이도는 easy인데 왜 이렇게 매번 시간이 오래 걸리는지 정말 ㅠㅠ 어떻게든 1시간 30분 안에 끝내려고 하는데 긴장을 하고 푸는데도 잘 안된다.

오늘의 경우 애초부터 접근이 잘못되었다고 생각하는데...
사전 README 작성을 통해 이 부분을 최대한 낮추려고 하고는 있지만 영 쉽지 않다.

어쨌든. map으로 삽질하던 중 '어? 이게 아니라 배열을 잘라서 합쳐야겠네?' 라는 생각이 들었고 그래서 또 헷갈리는 slice, splice, concat이 등장. 오늘은 TIL로 배열 자르고 합치는 메서드를 간략하게 정리하고자 한다.

와. 자바는 풀다가 GG. 오랜만에 자바 건드리니까 되던것도 안되는듯. 사람은 망각의 동물이고나.


문제 링크

CyclicRotation


Javascript

가드클로즈를 2개 만들고 시작했다.
코드가 너무 길어지는 것 아닌가? 라는 생각도 했는데...

그리고 갠적으론 지금 코드에서 가드클로즈 1, 2번의 순서를 바구는게 어떤가? 싶기도 하다. length를 구해주는 게 set을 만드는 것보다는 더 효율적이고 빠를 것 같아서 이를 앞으로 이동해주면 약간의 효율성을 높일 수 있지 않을까? 하는 생각.

function solution(A, K) {
  // Implement your solution here

  // 1. 가드클로즈. 배열이 하나의 원소로 이루어진 경우
  const set = new Set(A);

  if (set.size === 1) {
    return A;
  }

  // 2. 가즈클로즈. 로테이트 횟수와 배열 길이가 같은 경우
  if (K === A.length) {
    return A;
  }

  const indexOfFirstItem = A.length - (K % A.length);

  const front = A.slice(indexOfFirstItem);
  const result = front.concat(A.slice(0, indexOfFirstItem));

  return result;
}

splice

  • splice()의 중요한 점은 원본 배열을 변형한다는 것!! 예전에 reduce를 원하는 방식대로 사용하기 위해 splice를 몇 번 써보았다. 원본 배열을 변형시켰기 때문에 원하는 결과값을 얻을 수는 있었지만 과연 적절한 방법인지는 항상 의문 ㅎㅎ.
  • splice() 메서드는 배열의 기존 요소를 삭제 또는 교체하거나 새 요소를 추가하여 배열의 내용을 변경한다. 모던자바스크립트 튜토리얼에서는 '맥가이버 칼'이라는 표현을 사용한다.
  • 기본 syntax는 아래와 같다.
    - index, 즉 배열의 변경을 시작할 index 값이 필수이며 나머지 파라미터는 옵셔널이다. deleteCount는 제거하고자 하는 요소의 '갯수'를 나타내며 생략 시 index부터의 모든 요소를 제거한다. 당연히 이 count가 0일 경우 어떤 요소도 제거되지 않는다.
    - 그 이후의 파라미터는 배열에 추가할 요소를 나타해는데, 아무 요소도 지정하지 않는다면 splice 메서드는 요소를 제거하기만 한다.
arr.splice(index[, deleteCount, elem1, ..., elemN])
  • 원본 배열을 변형하는 splice의 경우 반환 값도 눈여겨 볼 필요가 있다. 바로 '제거한 요소를 담은 배열'을 리턴한다. 만약 아무것도 제거하지 않으면 빈 배열을 반환한다.
  • splice는 앞에서 얘기했듯이 맥가이버칼 처럼 삭제 뿐만 아니라 원하는 아이템을 중간에 삽입하기도 하는 다양한 기능을 하기에 헷갈릴 요소가 많다. 아래 2개의 예시를 통해 좀 더 익히는 것이 좋아보인다.

모던자바스크립트 예시

// 요소 세 개를 지우고 그 자리를 다른 요소 두 개로 교체
let arr = ["I", "study", "JavaScript", "right", "now"];

// 처음(0) 세 개(3)의 요소를 지우고, 이 자리를 다른 요소로 대체합니다.
arr.splice(0, 3, "Let's", "dance");

alert( arr ) // now ["Let's", "dance", "right", "now"]

MDN 예시

// 하나도 제거하지 않고, 2번 인덱스에 "drum"과 "guitar" 추가

var myFish = ['angel', 'clown', 'mandarin', 'sturgeon'];
var removed = myFish.splice(2, 0, 'drum', 'guitar');

// myFish is ["angel", "clown", "drum", "guitar", "mandarin", "sturgeon"]
// removed is [], no elements removed

slice

  • MDN 정의에 따르면 slice() 메서드는 어떤 배열의 시작부터 끝(끝은 미포함)에 대한 얕은 복사본을 새로운 배열 객체로 반환한다고 한다. 중요한 것은 원본 배열이 바뀌지 않는다는 점
  • 기본 syntax는 아래와 같다
arr.slice([start], [end])
  • 간혹 블로그 글을 보다보면 start 인덱스는 필수, end 인덱스는 optional이라고 설명하는 내용이 포함되어 있던데, MDN 문서의 매개변수 파트를 보면 명확히 써있었지만 둘 다 optional이다. 실제로 모던자바스크립트 튜토리얼에서도 아래와 같은 설명을 볼 수 있으니 파라미터 start, end 모두 optional이라고 이해하는 것이 맞다.

arr.slice()는 인수를 하나도 넘기지 않고 호출하여 arr의 복사본을 만들 수 있습니다.
이런 방식은 기존의 배열을 건드리지 않으면서 배열을 조작해 새로운 배열을 만들고자 할 때 자주 사용됩니다.

  • start, end는 모두 음수일 수 있는데 이 때는 배열 끝에서부터의 요소 개수를 의미한다. 이 부분은 헷갈리기 쉬워서 차라리 예시를 통해 이해하고 외우는 것이 낫다고 생각한다. 예시는 모두 모던자바스크립트 튜토리얼과 MDN에서 가져온 것이다.
let arr = ["t", "e", "s", "t"];

alert( arr.slice(-2) ); // s,t (인덱스가 -2인 요소부터 제일 끝 요소까지를 복사)
const animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];

console.log(animals.slice(2));
// Expected output: Array ["camel", "duck", "elephant"]

console.log(animals.slice(-2));
// Expected output: Array ["duck", "elephant"]

console.log(animals.slice(2, -1));
// Expected output: Array ["camel", "duck"]

console.log(animals.slice());
// Expected output: Array ["ant", "bison", "camel", "duck", "elephant"]

concat

  • 기존 배열의 요소를 사용해 새로운 배열을 만들거나, 기존 배열에 요소를 추가할 때 사용 가능하다. 기존 배열을 활용한다는 점에서 원 배열이 변형될 것 가지만 그렇지 않다. 기존 배열을 변경하지 않으며 추가된 새로운 배열을 반환한다.
  • 기본 syntax는 아래와 같다
array.concat(arg1, arg2...)

  • 인수로 배열이나 값이 올 수 있는데 갯수는 제한이 없다. (wow) 메서드 호출 시 array의 모든 요소, arg1, arg2 등에 속한 모든 요소를 한데 모은 새로운 배열이 반환된다.
  • 예시는 아래 참고. 값을 더할 때와 1차원 배열을 더할 때 어떻게 더해지는지를 눈여겨보면 좋을 것 같다.
const alpha = ['a', 'b', 'c'];

alpha.concat(1, [2, 3]);
// 결과: ['a', 'b', 'c', 1, 2, 3]
  • 특히 '객체'가 인자로 넘어올 때는 특이한 모습이 되는 것 같다. 배열처럼 보이는 유사 배열 객체라 하더라도 객체가 분해되지 않고 통으로 복사되어 더해진다.
let arr = [1, 2];

let arrayLike = {
  0: "something",
  length: 1
};

alert( arr.concat(arrayLike) ); // 1,2,[object Object]

문제를 풀다보면 은근히 자주 사용하게 되는데 이제 정리해놨으니 잊지말고 사용하자!

profile
가벼운 사진, 그렇지 못한 글

0개의 댓글