JS BASIC | 배열 (array)

chaen·2023년 7월 6일

JS Grammar

목록 보기
8/28
post-thumbnail

1. 배열이란?

다양한 변수를 한번에 묶어서 나열하는 방식으로, 순서가 있는 리스트이다.
배열 내부의 자릿수는 인덱스(index)라고 한다. : 0부터 시작함!
배열 내부의 자료형의 경우 문자열, 숫자, 배열, null, defined, 변수 등 다양하게 가능하다.

  • 배열 내부의 배열의 경우 이차원 배열이라고 한다.
  • 배열 내부의 값을 요소(element)라고 한다.
const fruits = ['사과', '오렌지', '배', '딸기'];
console.log(fruits[3]);
        
< 딸기

2. 배열 생성

1. 생성자 함수

var arr = new Array ('abc');

2. 배열 리터럴 [] 사용하기

var arr = ['abc'];

생성자 함수가 필수가 아니라면 배열 리터럴 방법을 추천


3. 배열 메서드

3-1. 배열 요소 갯수 구하기

배열 이름 뒤에 .length 붙이기

const emptyValue = [null, undefined, false, '', NaN];
console.log(emptyValue.length); //5

3-2. 원하는 인덱스의 요소 찾기

 // 마지막 요소: -1 (배열은 0부터 시작하기 때문에)
 // 뒤에서 2번째: -2
 console.log(arr[arr.length - 1]);

3-3. 요소 추가 (length, push, unshift)

배열.length: 배열 끝에 추가

//마지막 요소 인덱스가 배열.length - 1이므로 1을 더한다.
 const target = ['나', '다', '라', '마'];
 target[target.length] = '바';

push(): 배열 끝에 추가

target.push('바'); //["나", "다", "라", "마", "바"]

push 메서드는 push한 이유 배열의 총 길이를 반환한다.

const newLength = target.push('바'); //5

unshift(): 배열 앞에 추가

target.unshift('가'); //["가", "나", "다", "라", "마", "바"]

3-4. 요소 수정

const target = ['가', '나', '다', '라', '마'];
target[3] = '카';
console.log(target); //["가", "나", "다", "카", "마"]

3-5. 요소 제거 (pop. shift. splice. slice)

pop(): 마지막 요소 제거

  const target = ['가', '나', '다', '라', '마'];
  target.pop();
  console.log(target); //["가", "나", "다", "라"]

shift(): 첫 번째 요소 제거

 const target = ['가', '나', '다', '라', '마'];
 target.shift();
 console.log(target); //["나", "다", "라", "마"]

slice(a, b): 중간 요소 제거

  • 배열의 일부분을 추출하여 새 배열을 반환한다.
  • 원본 배열을 유지한다.
  const target = ['가', '나', '다', '라', '마'];
  console.log(target.slice(1, 3);); //['나', '다']
  console.log(target); // ['가', '나', '다', '라', '마'] (원본 유지)

a(첫번째): 시작 인덱스
b(두번째): 종료 인덱스 (해당 인덱스 미포함)

splice(a, b, c): 중간 요소 제거

  • 제거하게 되면 원본 배열이 수정된다.
  • a(첫 번째): 시작 인덱스
  • b(두 번째): 제거할 요소의 개수
  • (1, 1)일 경우 인덱스 1부터 1개를 제거하겠다는 의미
  • c(세 번째): 제거한 자리에 c 값을 삽입한다.
    const target = ['가', '나', '다', '라', '마'];
    target.splice(2, 2);
    console.log(target); //["가", "나", "마"]
               
    //제거한 자리에 다른 값 넣기
    const target = ['가', '나', '다', '라', '마'];
    target.splice(1, 3, '타', '파');
    console.log(target); //["가", "타", "파", "마"]

3-6. 키 값으로 추가, 수정, 제거하기

기본적인 배열이 아래의 형식으로 이루어져 있을 때,

const info = {
  ago: 20,
  name: "홍길동",
  wieght: "50kg"
}

프로퍼티 수정

info.ago = "25";
info["ago"] = "25";

프로퍼티 추가

info.height = "180cm";
info["height"] = "180cm";

프로퍼티 삭제

delete info.weight;
document.write(info.weight); //사용하지 않는 게 좋다는..?

3-7. 요소 탐색 (include, indexOf, lastIndexOf, findIndex, find)

include()

  • 배열에 특정 요소가 있는지 확인하는 메서드
 //include와 boolean
 const target = ['가', '나', '다', '라', '마'];
 const result = target.includes('다');
 const result2 = target.includes('카');
 console.log(result); // true 
 console.log(result2); // false

set 함수의 has()와 같은 기능이다. has()의 성능이 더 좋다.

indexOf와 lastIndexOf

  • 특정 요소의 인덱스를 찾아서 반환하는 메서드
  • 만족하는 요소가 없다면 -1을 반환함
  • 얉은 비교 (참조값)를 기준으로 동작함
    const target = ['라', '나', '다', '라', '다'];
    const result = target.indexOf('라');
    const result2 = target.lastIndexOf('라');
    const result3 = target.indexOf('가');
    console.log(result);
    console.log(result2);
    console.log(result3);
               
    0 //앞에서 0번째 인덱스 - 앞에서부터 찾음
    3 //앞에서 3번째 인덱스 - 뒤에서부터 찾음
    -1 //결과값이 없다

findIndex

  • 모든 요소를 순회하면서 콜백 함수의 조건을 만족하는, 특정 요소의 인덱스를 반환하는 매서드
  • 만족하는 요소가 없다면 -1을 반환함
  • 객체의 인덱스를 찾을 때 indexOf 대신 사용함
let arr = [1, 2, 3];
arr.findIndex((e) => e === 2) // 2의 인덱스 번호인 1이 반환됨

3-8. 배열 병합 (concat)

  • 두 개의 서로 다른 배열을 이어 붙여서 새로운 배열을 반환
let arr1 = [1, 2];
let arr2 = [3, 4];
let concatedArr = arr1.concat(arr2); //[1, 2, 3, 4]

3-9. 배열 정렬 (sort, reverse, toSorted, toReversed)

sort()

문자열의 유니코드를 따라 요소를 정렬

let arr = ["4", "8", "2", "0x11"];
arr.sort(); //['0x11', '2', '4', '8']

sort()의 문제점

  1. 일시적으로 문자열로 변경되어 정렬되기 때문에 숫자가 두 자릿수 이상으로 넘어가면 제대로 정렬되지 않는 상황 발생
  2. 대소문자가 구분되어 정렬되는 상황 발생
let nums = [1, -1, 4, 0, 2, 10 ,20];
nums.sort() // [-1, 0 , 1, 10, 2, 20, 4]

let fruits = ["apple", "Orange", "orange", "melon"];
fruits.reverse(); // ['Orange', 'melon', 'apple', 'orange']

이 문제를 해결하기 위해서는 고차함수를 이용해야 한다.

let ascending_order = (x, y) => {return x - y };
let descending_order = (x, y) => {return y - x };
let nums = [1, -1, 4, 0, 2, 10 ,20];

nums.sort(ascending_order) // [-1, 0, 1, 2, 4, 10, 20]
nums.sort(descending_order) // [20, 10, 4, 2, 1, 0, -1]

→ 두 수를 비교해서 양수( 앞의 수 > 뒤에 수)가 나오면 자리를 바꾸고, 음수(뒤의 수 < 앞의 수)가 나오면 자리를 바꾸지 않는다. 이 로직은 정렬 알고리즘에서 특정 순서를 유지하기 위한 규칙으로, sort 메서드는 비교 함수를 사용하여 배열의 요소를 서로 비교하고 정렬하는데, 이 때 반환값이 양수일 때는 두 요소의 순서를 바꿔주고, 음수일 때는 그대로 둬서 순서를 유지한다.

reverse()

배열의 순서를 반전시킨다

arr = ["2", "사과", "바나나"];
arr.reverse(); //['바나나', '사과', '2']

toSorted() / toReversed()

원본 배열을 수정하지 않고 요소들을 재정렬한 새로운 배열을 반환하는 복사 메서드입니다.

const values = [1, 10, 21, 2];
const sortedValues = values.toSorted((a, b) => a - b);
const reversedItems = values.toReversed();
console.log(reversedItems); // [2, 21, 10, 21]
console.log(sortedValues); // [1, 2, 10, 21]

4. 배열 메서드 순회

4-1. while, for

const target = ['가', '나', '다', '라', '마'];
          
//while문
let i = 0;
while (i < target.length) {
  console.log(target[i]);
  i++;
}
          
//for문
for (let i = 0; i < target.length; i++) {
   console.log(target[i]);
}
          
가
나
다
라
마

4-2. Array.forEach

주어진 함수를 배열 요소 각각에 대해 실행
참고: 반복문

🔍 반복문 예제

다음 배열에서 ‘라’를 모두 제거하세요.
indexOf 와 splice를 사용하세요.

const arr = ['가', '라', '다', '라', '마', '라'];

arr.forEach((index) => {
   let i = arr.indexOf('라');
   if (i){
       arr.splice(i, 1);
   }
 });

 console.log(arr); //[ '가', '다', '마' ]

5. 배열 조작 메서드

5-1. Arr.map

배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환한다.

const arr = [1,4,8,10];
const map = arr.map(x=>x*2);
console.log(map); //[2,8,16,20];

추가 참고 링크: JS BASIC | Map, Set

5-2. Arr.filter

주어진 함수의 테스트를 통화하는 모든 요소를 모아 새로운 배열로 반환한다.

const words = ["spray", "limit", "decoration", "excellent"];
const result = words.filter(word => word.length > 6 );
console.log(result); //["decoration","excellent"];

5-3. Arr.find

find 메소드는 주어진 판별 함수를 만족하는 첫 번째 요소의 값을 반환한다. 그런 요소가 없다면 undefined를 반환한다.

const inventory = [
  {name : 'apples', quantity : 2},
  {name : 'bananas', quantity : 4},
  {name : 'cherries', quantity : 9}
  ];

const result = inventory.find(fruit => fruit.name === 'bananas');

console.log(result); //  {name : 'bananas', quantity : 9}

5-4. Arr.every

every 메서드는 배열의 모든 요소가 주어진 판별 함수를 만족하는지 테스트한다. 모두 만족하면 true, 하나라도 실패하면 false를 반환한다

const isBelowThreshold = (currentValue) => currentValue < 40;
const array1 = [1, 30, 39, 29, 10, 13];
console.log(array1.every(isBelowThreshold)); // true

5-5. Arr.some

some() 메서드는 배열 안의 어떤 요소라도 주어진 판별 함수를 적어도 하나라도 통과하는지 검사한다.

const array = [1, 2, 3, 4, 5];
const even = (element) => element % 2 === 0;
console.log(array.some(even)); // true

someevery를 반복문처럼 쓰는 방법

some()이나 every() 안에서 조건을 만족하면 return true/false로 흐름을 끊을 수 있다. 이를 활용하면 forEach 대신 중간에 멈추는 반복문처럼 쓸 수 있다.

const arr = [5, 10, 15, 20, 25];
let sum = 0;
arr.some((value) => {
    sum += value;
    return sum > 30; // 합이 30을 넘으면 중단
});
console.log(sum); // 30 넘은 시점에서 멈춘 합 출력

5-6. Arr.reduce

배열의 각 요소에 대해 주어진 reducer(누산기) 함수를 실행하고, 하나의 결과값을 반환한다.

arr.reduce(callback[, initialValue]);
  • callback은 다음 네 가지 인수를 받는다.

    • accumulator 누산기. 콜백의 반환값을 누적. 콜백의 이전 반환값 혹은 첫 번째 호출.
    • currentValue 처리할 현재 요소
    • currentIndex 처리할 현재 요소의 인덱스. initialValue를 제공한 경우 0, 아니면 1부터 시작
    • array reduce()를 호출한 배열
  • initialValue (Optional) : callback의 최초 호출에서 첫 번째 인수에 제공하는 값. 초기값을 제공하지 않으면 배열의 첫 번째 요소를 사용. 빈 배열에서 초기값 없이 reduce()를 호출하면 오류 발생

// 예제
const nums = [1, 2, 3, 4];
const initalValue = 0;
let sum = nums.reduce(
  (acc, cur) => acc + cur, initalValue);
console.log(nums); //0 + 1 + 2 + 3 + 4 = 10

6. N차원 배열

  • 배열 안에 N개 만큼의 배열이 존재하는 객체
  • 2/3 차원 지도 정보, RBG 를 저장하는 2차원 사진 파일 등을 표현할 떄 활용 가능하다.
  • 2차원 배열은 array[N][M]으로 접근 가능하다.
let array = [
  [101, 102, 103],
  [201, 202, 203],
  [301, 302, 303],
  [401, 402, 403],
];
// array[4][3] - array 안 배열이 4개, 그 안에 배열이 각 3개

console.log(array);
// [ [ 101, 102, 103 ], [ 201, 202, 203 ], [ 301, 302, 303 ], [ 401, 402, 403 ] ]

/* length로 2차원 배열의 크기 구하기 */
console.log(array.length); // 4
console.log(array[0].length); // 3 

/* 각 요소에 접근 */
console.log(array[0]); // [ 101, 102, 103 ]
console.log(array[0][0]); // 101 

6-1. 배열의 요소 수정하기

  • 배열(Array) 전체를 push(), pop() 가능하다.
/* 행 전체 삭제 */
let popped_element = array.pop(); // 삭제하고 popped_element에 저장
console.log(array); // [ [ 101, 102, 103 ], [ 201, 202, 203 ], [ 301, 302, 303 ] ]
console.log(popped_element); // [ 401, 402, 403 ]

/* 요소 하나만 삭제하고 싶다면? */
let popped_element2 = array[0].pop(); // 삭제하고 popped_element2에 저장
console.log(popped_element2); // 103

/* 요소 추가 */
let array_num = array.push([501, 502, 503]); // 추가된 이후 행의 개수 저장
console.log(array); // [ [ 101, 102 ], [ 201, 202, 203 ], [ 301, 302, 303 ], [ 501, 502, 503 ] ]
console.log(array.length); // 4 

🔍 2차원 배열 반복문 예제

  • 이중 for loop를 사용한 2차원 배열 접근
let array = [
  [101, 102, 103],
  [201, 202, 203],
  [301, 302, 303],
  [401, 402, 403],
];

for (let i = 0; i < array.length; i++) {
  for (let j = 0; j < array[i].length; j++) {
    console.log(array[i][j]);
  }
} // 101 102 103 201 202 203 301 302 303 401 402 403

let recipe = [
  ["strawberry", 50],
  ["banana", 100],
  ["ice", 150],
]; // 배열의 각 요소가 서로 다른 자료형을 가질 수 있다

for (let i = 0; i < recipe.length; i++) {
  console.log(`fruit: ${recipe[i][0]}, amount: ${recipe[i][1]}`);
} // fruit: strawberry, amount: 50 
	// fruit: banana, amount: 100 

0개의 댓글