배열(array)

Featured image

배열(Array)


다수의 항목을 저장하는 기본 데이터 구조 역할. 배열 내 포함된 개별 항목을 요소라 하며, 숫자, 문자열, 객체 등을 포함한 다양한 범위의 데이터 유형을 포괄함.

예시1: [ ] 표기법을 사용하면 미리 정의된 값으로 배열을 인스턴스화하거나 후속 초기화를 위해 비워 둘 수 있습니다.

예시2: 배열 내의 요소는 해당 인덱스 번호를 참조하여 액세스할 수 있습니다. 인덱스는 배열 내의 요소 위치에 대한 식별자 역할을 하며 번호 지정 규칙은 0부터 시작합니다.

let myArray = [1, 2, 3, 4, 5];
console.log(myArray[0]); // 1
console.log(myArray[1]); // 2
let myArray = [1, 2, 3, 4, 5];
myArray[2] = 30;
console.log(myArray); // [1, 2, 30, 4, 5]

JS 배열 조작용 메서드: ‘push()’, ‘pop()’, ‘shift()’, ‘unshift()’, ‘slice()’, ‘splice()’, ‘sort()’ 등이 있음. ‘reverse()’, ‘concat()’, ‘join()’, ‘map()’, ‘filter()’ 및 ‘reduce()’. 이러한 메소드는 배열 요소의 추가, 제거, 정렬 및 조작을 용이하게 하는 목적으로 사용함.

배열 생성

다양한 접근 방식으로 배열 생성이 가능함. 일반적인 방법은 []표기법을 활용. Array 생성자 또는 Array.of() 메서드를 사용해 배열 생성도 가능함.

예시1: []표기법

let myArray = [1, 2, 3, 4, 5]; // 숫자 배열
let myStringArray = ["apple", "banana", "orange"]; // 문자 배열
let myOjectArray = [{name: "John", age: 30}, {name: "Jane", age: 25}] // 객체 배열

예시2: 배열 생성자 사용

let myArray = new Array(1, 2, 3, 4, 5); // 숫자 배열 
let myStringArray = new Array("apple", "banana", "orange") // 문자 배열 생성

예시3: Array.of() 메서드 사용

let myArray = Array.of(1, 2, 3, 4, 5); // 숫자 배열
let myStringArray = Array.of("apple", "banana", "oragne"); // 문자 배열

Array 생성자를 사용한 배열의 길이는 전달된 인수의 수에 따라 결정되며 인수가 제공되지 않는 경우 배열의 길이는 0이 됨.

배열 규칙

  1. []표기법 사용.
  2. Array 생성자, Array.of()메서드 사용.
  3. Array 생성자, Array.of()메서드의 차이점을 이해: Array 생성자는 주어진 길이의 배열을 생성하지만 Array.of()는 주어진 요소로 배열 생성.
  4. 배열 크기에 주의할 것, 대규모 배열은 메모리 및 성능 문제를 야기할 수 있음.
  5. 데이터 유형 지정: 배열에 저장하려는 데이터 유형을 지정할 것.
  6. 고유한 이름 사용: 충돌 방지
  7. 배열을 체계적으로 유지: 올바른 인덱싱으로 정리되었는가 확인.
  8. 불필요한 글로벌 스코프를 사용하지 말것: 스코프 오염이 발생할 수 있기 때문에 로컬 스코프로 할 것.

요소 접근법

배열 내 요소는 특정 위치의 개별 값을 의미함. 첫 번째 요소 인덱스는 0, 두 번째는 1임. 각 요소에 대해 0부터 1씩 증가함.

요소 접근 규칙

예1: 배열의 1번째 요소 접근법

let fruits = ["apple", "banana", "orange"];
console.log(fruit[0]); // output : "apple"

예2: 배열의 마지막 요소 접근법

let fruits = ["apple", "banana", "orange"];
console.log(fruits[fruit.length -1]); // output : "orange"

예3: 변수를 인덱스로 사용

let fruits = ["apple", "banana", "orange"];
let index = 1;
console.log(fruit[index]); // output : "banana"

예4: 음수 인덱스 사용해 마지막 요소 엑세스

let fruits = ["apple", "banana", "orange"];
console.log(fruit[-1]); // output : "orange"

예5: .slice() 메서드 사용. 일부 복사본 얻기.

  1. 추출 시작 인덱스
  2. 추출 종료 인덱스(결과에 미포함)
let fruits = ["apple", "banana", "orange"];
let subArray = fruits.slice(1,3);
console.log(subArray); // output : ["banana", "orange"]

예6: .splice()메서드는 배열 내 요소를 추가하거나 제거

let fruits = ["apple", "banana", "orange"];
fruits.splice(1, 1);
console.log(fruits); // output: ["apple", "orange"]

요소 업데이트

  1. 인덱스를 사용해 원하는 요소에 엑세스하고 =연산자를 사용해 새 값을 할당할 수 있음.
    let myArray = [1, 2, 3, 4, 5];
    myArray[2] = 30;
    console.log(myArray); // [1, 2, 30, 4, 5]
    
  2. ‘pop()’, ‘shift()’, ‘splice()’, ‘sort()’, ‘reverse()’, ‘concat()’, ‘fill()’, ‘ copyWithin()’, ‘map()’, ‘filter()’ 및 ‘reduce()’을 사용하면 조작할 수 있음.
    let myArray = [1, 2, 3, 4, 5];
    myArray.pop();
    console.log(myArray); // [1, 2, 3, 4]
    
  3. ‘map()’ 함수를 사용하면 배열 내의 각 요소에 콜백 함수를 적용하여 업데이트된 요소가 포함된 새 배열을 만들 수 있음. 반면 ‘filter()’ 함수를 사용하면 주어진 조건에 따라 배열 요소를 선택적으로 필터링할 수 있음. 각 요소를 평가 후 주어진 조건에 따른 배열 요소를 선택적으로 필터링할 수 있음.
    let myArray = [1, 2, 3, 4, 5];
    let newAray = myArray.map(function(element)){
     return element * 2;
    });
    console.log(newArray); // [2, 4, 6, 8, 10]
    
  4. 배열 요소에 대한 보다 복잡한 작업의 경우 for 루프의 기능을 활용함. for 루프를 활용하면 배열의 각 요소를 반복하고 사용자 지정 작업이나 변환을 수행할 수 있음.
    let myArray = [1, 2, 3, 4, 5];
    for(let i = 0; i < myArray.length; i++){
     myArray[i] = myArray[i] * 2;
    }
    console.log(myArray); // output: [2, 4, 6, 8, 10]
    

JS 배열은 참조 유형임. 배열 내 요소를 업데이트하면 변경 사항이 해당 배열에 대한 모든 참조에 전파됨. ‘map()’ 및 ‘filter()’ 함수와 같은 내장 배열 메서드를 활용하고 for 루프를 활용하면 프로세스를 크게 단순화하고 능률화할 수 있음.

배열 요소 업데이트 규칙

  1. 요소의 인덱스 사용
  2. 할당 연산자 사용
  3. 배열 정리 유지
  4. 내장 배열 메서드 사용: pop( ), shift( ), splice( ), sort( ), reverse( ), concat( ) 등.
  5. map( )filter( ) 함수 사용

let과 const를 사용해 배열 결합

배열 결합은 concat() 메서드나 확산 연산자 (...)를 사용하여 수행

예1: concat() 메서드 사용. concat() 메서드는 여러 배열을 하나의 배열로 병합할 수 있음. 원래 배열은 변경되지 않은 상태로 두 개 이상의 배열을 결합 가능함.

let array1 = [1, 2, 3];
let array2 = [4, 5, 6];
let combinedArray = array1.concat(array2);
console.log(combinedArray) // [1, 2, 3, 4, 5, 6]

예2: 스프레드 연산자 사용 (…) 확산 연산자 ‘(…)’는 해당 요소를 새 배열로 확산하여 배열을 결합할 수 있음.

let array1 = [1, 2, 3];
let array2 = [4, 5, 6];
let combinedArray = [...array1, ...array2];
console.log(combinedArray) // [1, 2, 3, 4, 5, 6]

예3: let과 const 사용. ‘let’ 및 ‘const’ 키워드를 활용하면 병합 프로세스의 결과로 결합된 배열을 저장가능.

let array1 = [1, 2, 3];
let array2 = [4, 5, 6];
let combinedArray = array1.concat(array2);
console.log(combinedArray); // [1, 2, 3, 4, 5, 6]

예4: 스프레드 연산자를 사용하여 배열을 단일 값과 결합.

let array1 = [1, 2, 3];
let combinedArray = [...array1, 4];
console.log(combinedArray); // [1, 2, 3, 4, 5, 6]

예5: 스프레드 연산자를 사용해 배열을 여러 값과 결합.

let array1 = [1, 2, 3];
let combinedArray = [4, 5, ...array1, 4];
console.log(combinedArray); // [4, 5, 1, 2, 3, 6]

예6: 스프레드 연산자를 사용하여 배열과 객체 결합.

let array1 = [1, 2, 3];
let array2 = [4, 5, 6];
let obj = {a: 1, b: 2};
let combinedArray = [...obj, ...array1, ...array2];
console.log(combinedArray); // [1, 2, 1, 2, 3, 4, 5, 6]

letconst를 사용하면 병합된 결과 배열을 저장가능. concat() 메서드는 원 배열의 모든 요소로 새 배열을 만드는 반면, 스프레드 연산자는 배열 요소를 새 배열로 확장함. 스프레드 연산자를 사용할 때는 요소 순서를 고려하는게 중요하고, concat() 메서드는 원 배열을 변경하지 않지만 스프레드 연산자는 변경한다는 점에 유의.

let 및 const 결합 규칙

  1. concat() 메서드 또는 확산연산자(...) 사용.
  2. letconst 를 사용해 결합된 배열 저장.
  3. 고유한 이름 사용.
  4. 배열 정리 유지
  5. 요소 순서를 염두에 둘것.
  6. 배열 크기에 주의.
  7. 원본 배열에 유의.
  8. concat()과 스프레드 연산자의 차이점 이해: concat() 메서드는 원래 배열의 모든 요소를 포함하는 새 배열을 반환, 스프레드 연산자는 배열 요소를 새 배열로 분산시키는 데 유용.`

Length 속성

‘.length’ 속성은 배열 내의 요소 수 또는 문자열 내의 문자 수를 결정하는 목적으로 사용. 배열에 적용하면 .length 속성은 배열에 포함된 총 요소 수를 제공함.

 let myArray = [1, 2, 3, 4, 5];
 console.log(myArray.length); // 5

JS의 ‘.length’ 속성은 읽기 전용이며 검색은 되지만 수정은 안됨. 또한 1부터 요소나 문자 수를 카운트함.

배열이 본질적으로 동적이며 크기가 수정될 수 있으니만큼, .length 속성은 배열에서 요소를 추가하거나 제거할 때 유용함. .push() 메서드 사용시 배열 끝에 요소를 추가할 수 있고, .pop() 메서드로는 마지막 요소를 제거할 수 있음.

예1: .length 속성으로 배열 끝에 요소 추가하기

let myArray = [1, 2, 3, 4, 5];
myArray[myArray.length] = 6;
console.log(myArray); //[1, 2, 3, 4, 5, 6]
console.log(myArray.length); // 6

예2: .length 속성으로 배열 끝에 요소 제거하기

let myArray = [1, 2, 3, 4, 5];
myArray.length = myArray.length -1;
console.log(myArray); //[1, 2, 3, 4]
console.log(myArray.length); // 4

예3: .length 속성으로 배열 반복하기

let myArray = [1, 2, 3, 4, 5];
for (let i = 0; i < myArray.length; i++ ){
    console.log(myArray[i]);
}

.length 속성 사용 규칙

  1. .length는 메서드가 아닌 속성이라 괄호 호출 불가능.
  2. .length는 배열의 요소 수 또는 문자열의 문자 수를 반환
  3. .length 속성은 읽기 전용입니다. 즉, 속성 값을 검색하는 데 사용할 수 있지만 설정하는 데는 사용할 수 없음.
  4. .length는 1부터 요소나 문자 수를 세기 시작하고, 배열이나 문자열의 첫 번째 요소나 문자부터 세기 시작.
  5. .length 속성을 사용하여 배열에서 요소를 추가하거나 제거
  6. .length는 배열 및 문자열 객체의 속성이므로 다른 유형의 객체와 함께 사용할 수 없음.
  7. .length 속성을 사용하면 배열을 반복하여 각 요소에 액세스가능
  8. .length는 객체의 속성 수를 계산하지 않으며 배열의 요소 수 또는 문자열의 문자 수만 계산함.

.push() 메서드

‘.push()’ 메서드를 사용하여 배열 끝에 하나 이상의 요소를 추가할 수 있음. 원래 배열이 수정되고 배열 길이가 결과로 반환됨. 요소를 기존 배열에 편리하고 효율적으로 추가.

let myArray = [1, 2, 3];
myArray.push(4);
console.log(myArray); // [1, 2, 3, 4]

단일 요소 외에도 여러 요소를 추가할 수도 있음.

let myArray = [1, 2, 3];
myArray.push(4, 5, 6);
console.log(myArray); // [1, 2, 3, 4, 5, 6]

새 배열이 생성되는 것이 아니라 원 배열이 수정됨. 또한 새 length가 반환되므로 요소 추가 후 업데이트 된 길이에 엑세스 할 수 있음.

.pop() 메서드

‘.pop()’ 메서드를 사용하여 배열의 마지막 요소를 제거할 수 있음. 끝에서 요소를 제거하고 원래 배열을 수정하며 제거된 요소를 반환함. 배열의 길이도 업데이트 됨.

let myArray = [1, 2, 3];
let lastElement = myArray.pop();
console.log(myArray); // [1, 2]
console.log(lastElement); / 3

배열이 비어 있고 ‘.pop( )’ 메서드가 호출되면 오류를 발생시키지 않고 undefined를 반환한다는 점은 주목할 가치가 있음, 또한 ‘.pop( )’ 메서드는 새 배열을 만드는 대신 마지막 요소를 제거하여 원래 배열을 수정함.

.pop() 메서드 규칙

  1. .pop( ) 메서드는 배열에서 마지막 요소를 제거하고 이를 반환.
  2. .pop( ) 메서드는 원래 배열을 수정하지만 새 배열을 생성하지는 않음.
  3. .pop( ) 메서드는 제거된 요소를 반환하므로 변수에 할당하거나 표현식에 사용할 수 있음.
  4. .pop( ) 메서드는 비어 있지 않은 배열에만 사용할 수 있습니다. 배열이 비어 있으면 오류없는 undefine을 반환함.
  5. .pop( ) 메서드는 배열에 사용하도록 특별히 설계되었습니다. 배열이 아닌 객체에 사용하면 undefine‘을 반환.
  6. .pop( ) 메서드는 또한 배열의 length 속성을 변경하고 요소를 제거한 후 1씩 줄임.
  7. .pop( ) 메서드는 다른 배열 메서드와 연결되어 단일 명령문으로 배열에 대해 여러 작업을 수행할 수 있음.
  8. .pop( ) 메서드는 어떤 인수도 허용하지 않으며 값에 관계없이 배열에서 마지막 요소를 제거.

배열과 함수

배열과 함수는 서로 상호작용하는데 일반적으로 배열을 함수에 인수로 전달하여 배열 내 요소에 작동하는 함수를 만드는 것임.

function doubleValues(arr){
    for(let i = 0; i < arr.length; i++){
        arr[i] = arr[i] * 2;
    }
    return arr;
}
console.log(doubleValues([1, 2, 3])); // [2, 4, 6]

다른 응용법은 함수 내에서 배열 메서드를 활용하는 것. 예를 들어 .forEach()메서드의 기능을 활용해 배열 요소를 반복하고 각 요소에 대해 원하는 작업을 실행할 수 있음. 이 접근 방식은 명시적인 루프 구성 없이 배열의 모든 요소에 함수를 편리하게 적용할 수 있음.

function printValues(arr){
    arr.forEach(function(element){
        console.log(element);
    });
}
printValues
({1, 2, 3}); // logs "1", "2", "3"

배열 .map() 메서드롤 활용해 원래 배열 요소 기반으로 새 배열을 생성할 수 있음.

function doubleValues(arr){
    return arr.map(function(element)){
        return element * 2;
    });
}
console.log(doubleValues([1, 2, 3])); // [2, 4, 6]

함수에서 배열을 반환하고 나중에 사용하려고 변수에 할당할 수 있음.

function getNumber(){
    return [1, 2, 3];
}
let numbers = getNumbers();
console.log(numbers); // [1, 2, 3]

배열과 함수는 배열을 함수 인수로 전달하고 함수 내에서 배열 메서드를 활용, 기존 배열 기반으로 새 배열을 만들거나 함수에서 배열을 반환해 이를 변수에 할당하는 등의 방법으로 활용이 가능함.

배열과 함수 규칙

  1. 배열은 함수에 인수로 전달될 수 있으므로 함수가 배열 요소에 대해 작업을 수행할 수 있음.
  2. .forEach( ), .map( ), .filter( ), .reduce( ) 등과 같은 배열 메서드를 함수 내에서 사용하여 배열 요소에 대한 작업을 수행할 수 있음.
  3. 함수는 배열을 반환할 수 있으므로 호출자가 반환된 값을 변수에 할당하고 배열로 작업할 수 있음.
  4. 배열 요소는 변경 가능합니다. 즉, 해당 값이 생성된 후에도 변경될 수 있음.
  5. 배열 요소는 숫자, 문자열, 객체 및 기타 배열을 포함한 모든 유형
  6. 배열은 객체이므로 다른 객체처럼 액세스할 수 있는 속성과 메서드를 갖음.
  7. JS의 배열 메소드 대부분은 원래 배열을 변경하지 않고, 대신 원하는 변경 사항이 포함된 새 배열을 반환.
  8. JS 배열 인덱스는 0부터 시작.

더 많은 배열 기능

  1. .forEach() 메소드는 배열의 각 요소를 반복하고 각 요소에 대해 특정 작업을 수행할 수 있는 편리한 도구임. for 루프를 작성할 필요 없이 배열을 반복하고 각 요소에 코드를 실행하는 편리함을 제공.
    let myArray = [1, 2, 3];
    myArray.forEach(function(element)){
     console.log(element);
    });
    
  2. .map() 메서드는 제공된 함수를 원본 배열의 각 요소에 적용한 결과를 바탕으로 새 배열을 생성하는 함수. 배열의 각 요소에 대해 실행되는 콜백함수를 인수로 사용.
    let myArray = [1, 2, 3];
    let newArray = myArray.map(function(element)){
     return element * 2;
    });
    console.log(newArray); // [2, 4, 6]
    
  3. .filter() 메서드는 제공된 함수에 의해 구현된 지정 조건을 통과한 요소로 새 배열을 생성함.
    let myArray = [1, 2, 3, 4, 5];
    let newArray = myArray.filter(function(element)){
     return element % 2 === 0;
    });
    console.log(newArray); // [2, 4]
    
  4. .reduce() 메서드는 배열 요소를 왼쪽에서 오른쪽으로 적용하고 단일 값으로 줄이기 위해 콜백함수를 배열 요소에 적용함.
    let myArray = [1, 2, 3, 4, 5];
    let total = myArray.reduce(function(accumulator, currentValue){
     return accumulator + currentValue;
    }, 0);
    console.log(total); // 15
    
  5. .sort() 메서드는 배열의 요소를 제자리에 정렬하고 정렬된 배열을 반환함. 새 배열을 만들지 않고 원본 배열을 직접 수정함. 비교를 위해 UTF-16 코드 단위값을 사용함. 특정 기준에 따른 정렬순서를 정의하기 위해 사용자 정의 비교함수를 인수로 넣을 수 있음. 비교 함수는 결과에 따라 음수, 0, 양수 값을 반환해야 함.
    • a가 b보다 작으면 음수 값
    • a가 b보다 크면 양수 값
    • a와 b가 동일한 것으로 간주되어야하면 0
let myArray = [3, 1, 2];
myArray.sort();
console.log(myArray); // [1, 2, 3]
  1. .slice() 메서드는 기존 배열의 일부 복사본인 새 배열을 반환함. 원본 배열을 수정하지 않고도 배열의 특정 섹션을 추출할 수 있음. 끝 인덱스는 미포함.
let myArray = [1, 2, 3, 4, 5];
let netArray = myArray.slice(1, 3);
console.log(newArray); // [2, 3]
  1. .concat() 메서드는 호출된 배열을 인수로 전달된 다른 배열 또는 값과 결합하는 새 배열을 반환함. 원래 배열은 수정되지 않으며, 이 메서드로 여러 배열의 모든 요소를 포함하는 새 배열을 만들거나 기존 배열에 개별 값을 추가할 수 있음.
let myArray = [1, 2, 3];
let newArray = myArray.concat([4, 5], [6, 7]);
console.log(newArray); // [1, 2, 3, 4, 5, 6, 7]
  1. .indexOf()메서드는 배열의 특정 요소의 첫 번째 인덱스를 반환하거나 해당 요소를 찾을 수 없는 경우 -1을 반환.
let myArray = [1, 2, 3, 4, 5];
let index = myArray.indexOf(3);
console.log(index); //2

중첩 배열(nestedArray)

배열의 배열 요소임. 배열 내 계층 구조를 만들 수 있음. 배열 구조를 탐색하려면 추가 인덱스를 사용해 각 중첩 수준에 엑세스함.

‘nestedArray’ 는 요소로 3개의 배열로 구성된 중첩 배열로서 1번째 배열의 2번째 요소에 엑세스 하려면 nestedArray[0][1] 인덱스를 사용함.

let nestedArray = [[1, 2], [3, 4], [5, 6]];
console.log(nestedArray[0],[1]); //2 

중첩 배열은 일반 배열과 마찬가지로 .push(),.concat(),.splice() 등의 다양한 배열 메서드를 사용할 수 있음. 중첩 배열은 복잡한 데이터 구조를 표현하고 구성하는데 유용함.

let nestedArray = [[1, 2], [3, 4]];
nestedArray[0].push(5);
console.log(nestedArray); // {[1, 2, 5], [3, 4]}

중첩 배열 처리 시 중첩 수준 내 특정 요소에 엑세스하려면 적절한 인덱스를 고려해야하며 다차원 배열 개념과 인덱스가 외부 배열에서 내부 배열로 계단식 배열인 것을 이해해야 함.

예1: 행렬을 나타내는 2D 배열

let matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
console.log(matrix[0][1]); //2

예2: 학생 목록 및 정보

let students = [["John", 25, "male", ["math" , "history"]], ["Emily", 23, "female", ["chemistry", "physics"]], ["Micheal", 27, "male", ["biology", "computer science"]]];
console.log(student[0],[0]+ " is " + student[0][2] + " and is taking " + student[0][3][1] + " class."); // john is male and is taking history class.

예3: 레스토랑 메뉴 및 하위 항목

let menu = [["Appetizers", ["Wings", "Nachos", "Morrarella Sticks"]],["Entrees", ["Steak", "Fish and Chips", "Spaghetti"]], ["Desserts",["Cheesecake", "Tiramisu", "Creme Brulee"]]];
console.log("Our menu includes: " + menu[0][1][1] + menu[1][1][1] + " , and" + menu[2],[1],[1] + ".");
// Our menu includes: Nachos, Fish, and Chips, and Tiramisu.

예4: 장바구니

let cart = [    ["Apple", 2, 0.5], ["Banana", 5, 0.25],["Orange", 3, 0.75]];
console.log(cart[1],[0] + " " + cart[1][1] + " " + cart[1][2]*cart[1][1]); // banana 5 1.25

중첩배열 규칙

  1. 중첩 배열의 요소에 엑세스하려면 각 중첩 수준마다 하나씩 여러 인덱스가 필요함. ‘nestedArray[0][1]’ 등
  2. 중첩 배열 요소를 수정하려면 중첩 수준마다 하나씩 여러 인덱스가 필요함. 두 번째 요소를 변경하려면 할당 연산자 ‘nestedArray[0][1] = newValue’를 사용함.
  3. 배열의 길이 속성은 배열의 요소 수를 반환함.
  4. .push( ), .concat( ), .splice( ), .map( ) 등의 Array 메서드는 일반 배열과 같이 사용가능.
  5. 중첩 배열 반복시 중첩 수준과 요소에 엑세스 하려면 올바른 인덱스를 사용해야함.
  6. .sort() 또는 .splice() 같은 원래 배열을 수정하는 메서드 사용시 주의할 것. 이런 메서드는 원래 배열을 변경함.
  7. 크고 복잡한 중첩 배열 작업시 함수를 사용해 동일 논리의 중복을 피하고 코드 가독성을 늘림.
  8. 중첩 배열을 조작하는 것은 일반 배열보다 더 복잡하므로 작동방식을 이해해야 함.