2024/03/13 배열과 메서드2

YIS·2024년 3월 13일
post-thumbnail

배열을 변형하는 메서드

sort

배열의 요소를 문자열로 변환하고 유니코드 코드 포인트(사전편집순)의 순서에 따라 정렬.
그래서 숫자 정렬이나 다른 기준으로 정렬하고 싶은 경우,
따로 정렬기준을 함수로 만들어서 넘겨줘야됨.
넘겨줄때 반드시 함수는 두 개의 비교값이 필요하고, 반환값도 있어야됨.
원본 배열을 직접 변경함.

기본문법
array.sort(); 기본 사용법
array.sort(function(a, b) { return a - b; // 오름차순 정렬 }); 비교함수를 사용하는 법

<script>
function compare(a, b) {
  if (a > b) return 1; // 첫 번째 값이 두 번째 값보다 큰 경우
  if (a == b) return 0; // 두 값이 같은 경우
  if (a < b) return -1; //  첫 번째 값이 두 번째 값보다 작은 경우
}
let arr = [ 3, 1, 4, 2 ];

arr.sort(compare);

alert(arr);  // 1, 2, 3, 4
</script>

일단 비교함수 compare를 반복적으로 호출함.이때 arr안에 요소들이 순서대로 전달됨.
이때 중요한게
a 는 b보다 "크다" >> 1 양수를 반환, 위치가 서로바뀜
a 와 b는 서로 "대등" >> 0 위치 그대로
a 는 b보다 "작다" >> -1 음수를 반환 위치가 그대로
단순히 위 예시는 오름차순으로 정렬할 때 일반적인 정렬함수임.

양수일때 위치가 바뀌고 대등,작을때 그대로
이 규칙은 자바스크립트 sort()매서드에서 사용되는 약속임 .

그래서 일단 3과1을 부른후 비교 .a(3)>b(1) 3(a)이 크기 때문에 리턴값이 1,즉 양수가 나옴
그럼 위에 약속에서 양수반환시 크다로 간주. 위치가 바뀜 [1,3,4,2]가 됨.
그다음 3과4를 불러 비교. a(3)<b(4) 3(a)이 작기 때문에 -1이 리턴. 음수임
그래서 위치 그대로 [1,3,4,2]
4와2를 비교 4(a)>2(b) 보다 크기 때문에 1,양수를 반환 위치가 바뀜.
[1,3,2,4]가 됨.
3과 2도 비교하게되면 결국 [1,2,3,4]가 됨.

그럼 좀더 식을 간단하게 표현도 가능함. 결국 비교값이 양수냐 음수냐에따라 위치가 바뀌는거니까

<script>
let arr = [3,1,4,2];

arr.sort(function(a,b){
  return a-b;
});
alert(arr);
</script>

3(a)-1(b)은 2니까 양수 >> 위치바뀜
3(a)-4(b)는 -1이니까 음수 >> 위치그대로... 이런식으로



reverse

배열요소를 역순으로 정렬시켜줌. 원본배열을 직접 변경함.
문자열에 직접 사용불가. 문자열을 배열로 변환후 reverse 적용후 다시 문자열로 합쳐야함.

기본문법
array.reverse();

  <script>
  let arr = [1, 2, 3, 4, 5];
  arr.reverse();

  alert( arr ); // 5,4,3,2,1
  </script>


split

문자열을 지정한 구분자를 기준으로 여러 개의 부분 문자열 쪼개고 나눠진 요소들을 배열로 반환.
원본 문자열에는 영향을 주지않고 분열된 문자열을 포함하는 새 배열을 생성.
구분자는 콤마(,)가 될 수도, 빈문자열("")이 될 수도 있고, 공백(" ")등등 될 수 있다.


기본문법
let array = string.split(separator, limit);

  • string : 분할하고자 하는 원본 문자열
  • separator : 문자열을 분할하는 기준이 되는 문자열이나 정규 표현식.
    구분자는 결과 배열에 포함되지 않음. separator가 생략되거나 빈 문자열('')로 지정되면,
    원본 문자열의 각 문자를 요소로 하는 배열이 반환
  • limit(선택적) : 반환할 배열의 최대 길이.
<script>
let names = 'Bilbo,Gandalf,Nazgul';

let arr = names.split(",");
//구분자가 콤마(,)인 경우
for (let name of arr) {
  alert( `${name}에게 보내는 메시지` ); 
}
</script>
<script>
let names = 'Bilbo Gandalf Nazgul';
      
let arr = names.split(" ");     
//구분자가 공백(" ")인 경우      
for (let name of arr) {
  alert( `${name}에게 보내는 메시지` ); 
}      
</script>
<script>
let names = 'Bilbo Gandalf Nazgul';
      
let arr = names.split("");
//구분자가 빈문자열("")인 경우
//이경우는 문자열의 각 문자가 배열의 개별 요소로 분할
//공백도 문자로 간주되어 배열에 포함 .ex)["B", "i", "l", "b", "o", " ", "G", "a",...] 이런식      
for (let name of arr) {
  alert( `${name}에게 보내는 메시지` ); 
}
</script>
<script>
let names = 'Bilbo-Gandalf-Nazgul';
      
let arr = names.split("-");
//구분자가 하이픈(-)인 경우      
for (let name of arr) {
  alert( `${name}에게 보내는 메시지` ); 
}
 </script>


join

split과 반대, 배열의 모든 요소를 연결하여 하나의 문자열로 만들어 줌.
배열의 요소 사이에 삽입할 문자열(구분자)을 인자로 받을수 있음.
구분자 생략시 배열의 요소들은 콤마(,)를 사용해 연결됨


기본문법
array.join(separator)

  • separator(선택적) : 배열의 각 요소를 구분할 문자열을 지정.
let arr = ["Bilbo", "Gandalf", "Nazgul"];
let str = arr.join(); // 구분자를 지정하지 않았으므로 기본값인 콤마(,)적용.
console.log(str); // "Bilbo,Gandalf,Nazgul"
<script>
  let arr = ['Bilbo', 'Gandalf', 'Nazgul'];
  let str = arr.join('-'); //구분자가 하이픈('-')인 경우
alert( str ); // Bilbo-Gandalf-Nazgul
</script>
let arr = ["Bilbo", "Gandalf", "Nazgul"];
let str = arr.join(" "); // 공백(" ")을 구분자로 사용
console.log(str); // "Bilbo Gandalf Nazgul"
let arr = ["Bilbo", "Gandalf", "Nazgul"];
let str = arr.join(""); //빈 문자열("")을 구분자로 사용하는 경우
console.log(str); // "BilboGandalfNazgul"


reduce 와 reduceRight

reduce : 배열을 순차적으로 돌면서 값 하나를 도출함.
배열의 각 요소에 대해 주어진 리듀서(reducer) 함수를 실행하고, 하나의 결과값을 반환
4개의 인자를 받는데 보통은 2개를 씀, accumulator, currentValue
배열을 순회하며 단일 값으로 줄여나가는 과정에서 매우 유용하게 사용


기본문법
array.reduce(callback(accumulator, currentValue, currentIndex, array), initialValue)

  • callback : 배열의 각 요소에 대해 실행할 함수. 이 함수는 네 개의 인자를 받음.
  • accumulator : 콜백의 반환값이 누적되는 변수. 초기값(initialValue)이 제공되면, 그 값이 첫 번째 호출에서 accumulator의 값이 됨.
  • currentValue : 처리할 현재 요소의 값.
  • currentIndex(선택적) : 처리할 현재 요소의 인덱스. 초기값이 제공되면 0부터 시작하고, 그렇지 않으면 1.
  • array(선택적) : reduce 메서드를 호출한 배열.
  • initialValue(선택적) : accumulator에 최초로 제공되는 값. 이 값이 제공되지 않으면, 배열의 첫 번째 요소가 accumulator의 초기값으로 사용되고, currentValue는 배열의 두 번째 요소부터 시작.
<script>
const numbers = [1, 2, 3, 4];
const sum = numbers.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
console.log(sum); // 10
</script>
<script>
const numbers = [1, 2, 3, 4];
const sum = numbers.reduce(function(accumulator, currentValue) {
  return accumulator + currentValue;
},0);
console.log(sum); // 10
</script>

화살표함수와 펑션을 쓴 방법. 개인적으론 펑션이 익숙함. 웹디실기볼때 펑션으로 외웠기 때문(...)

일단 initialValue값, accumulator의 첫 번째 호출에 제공되는 값임.
위의 예시에선 0이다. 이걸 생략하면 배열의 첫번째 요소를 사용하게됨.
다만 배열이 빈 배열일 경우 생략시 오류가 발생 하므로,가능하면 초기값(initialValue) 설정하는걸 추천.
accumulator에 0 초기값이 들어가고 currentValue에 배열 첫번째 요소인 1이 들어감. 0+1 =1
다시 돌아와서 accumulator는 누적계산의 결과값이다. 방금 더한값 1+ 현재요소 2 =3
다시 돌아와서 accumulator는 3이되고 currentValue는 3... 이런식으로 하면 결과가 10이나옴

<script>
const items = [{price: 10}, {price: 120}, {price: 1000}];
const total = items.reduce((accumulator, item) => accumulator + item.price, 0);
console.log(total); // 1130
</script>

이런식으로 객채배열에서 속성값을 구할수도 있다.

const fruits = ['apple', 'banana', 'orange', 'apple', 'orange'];
const count = fruits.reduce(function(accumulator, currentValue){
   accumulator[currentValue] = (accumulator[currentValue] || 0) + 1;
   return accumulator;
},{})
console.log(count); // { apple: 2, banana: 1, orange: 2 }

fruits 상수에 .reduce() 메서드를 호출하고, 이 메서드는 두 개의 매개변수(accumulator, currentValue)를 가진 콜백 함수와 초기값 {}을 인자로 받음(0이 아닌 빈객채를 설정함). reduce 메서드의 결과는 count 상수에 넣음.
함수를 순서대로 돌아보자.처음은 apple.
빈객채에다가 accumulator[currentValue]값은(accumulator[currentValue] || 0)+1
이부분이 이해가 안되서 검색해봤다. 원래 알고있는거라면 ||이거는 or연산자
A or B 둘중에 하나만 true여도 true값을 반환한다로 단순하게 알고있었는데 그게아님.

or연산자는 "첫 번째 truthy 값을 반환하거나, 두 번째 피연산자를 반환.
모든 값이 falsy할 경우 마지막 값을 반환한다"

분명히 한번 훑고 지나갔던 부분임. 대충이해하고 넘어갔던게 여기서 꽤나 이해하는데 어려웠다.

다시. 현재 accumulator[currentValue]에 apple값이 없으므로 falsy한 값임.그래서 두번째피연산자인 0을 반환할려고 하는데 애도 falsy한 값임. 둘다 펄시한 값이기때문에 마지막 값인 0을 반환함. 그리고 거기에 +1
그럼결국 accumulator['apple']이 1이 되고 다시 함수 반복.
banana,orange도 똑같이 1되고, 다시 4번째 apple순서에서는 accumulator[currentValue]이값 apple >> 1이 있음. 1은 truthy한 값이기때문에 1을 반환. +1하면 2 apple은 2가됨.
5번째 orange도 마찬가지로 2가됨. 그래서 { apple: 2, banana: 1, orange: 2 } 이값이 나옴.



reduceRight : reduce와 처리방향이 반대임. 즉 오른쪽(마지막요소)에서 왼쪽(첫번째요소)로

기본문법
array.reduceRight(function(accumulator, currentValue, currentIndex, array) { 함수의 실행 로직 }, 초기값);

<script>
const words = ['세계', '안녕'];
const greeting = words.reduceRight((acc, word) => acc + word,"");
console.log(greeting); // "안녕세계"
</script>
profile
엉덩이가 무거운 사람

0개의 댓글