프론트엔드/Javascript

자바스크립트 문법 6 - 배열 (Array) 의 기본

syleemomo 2021. 10. 9. 12:20
728x90

 

* 배열의 개념

배열은 서로 관련된 데이터끼리 그룹으로 묶어 놓은 변수이다. 예를 들어 소나타, 카니발, 람보르기니 등과 같은 여러 종류의 자동차를 하나로 묶어서 자동차라는 배열로 관리할 수 있다. 배열은 데이터베이스에서는 컬렉션(collection)이라고 부르기도 한다. 

 

* 배열을 사용하는 이유 (데이터 그룹핑)

const fruit1 = "apple"
const fruit2 = "banana"
const fruit3 = "orange"
const fruit4 = "watermelon"
const fruit5 = "strawberry"

배열을 사용하지 않으면 변수를 여러개 사용해야 한다. 

const fruits = ["apple", "banana", "orange", "watermelon", "strawberry"]

배열을 사용하면 관련된 데이터를 그룹으로 묶어서 사용할 수 있다. 

 

* 배열 타입 체크

Array.isArray(타입검사에 사용할 변수)

Array 객체에는 isArray 라는 메서드가 기본적으로 내장되어 있다. 인자로 타입검사에 사용할 변수를 넣어주면 불리언 형태(true, false)로 반환해준다. 

Array.isArray(["apple", "orange", "banana"]);  // true
Array.isArray({name: 'syleemomo', age: 23}); // false
Array.isArray('syleemomo');   // false
Array.isArray(undefined);  // false
Array.isArray(null);  // false
Array.isArray(3);  // false

 

* 자바스크립트 배열이 다른 프로그래밍 언어의 배열과 다른점

자바스크립트 배열은 실제로는 객체라서 어떤 자료형도 넣을수 있다. 즉, 같은 자료형이 아니라도 함께 그룹핑 가능하다. 예를 들어 아래와 같이 선언 가능하다. 

const mixedArray = [
    'apple', 3, undefined, [1,4, 7, 2], null, 
    {movieTitle: 'Harry potter', release: '2019-02-13'}, 3.131592]
    
console.log(mixedArray)

위 코드에는 문자열, 정수, 실수, 배열, 객체, undefined, null 이라는 복합적인 자료형이 들어가 있다. 이것은 자바스크립트 배열이 실제로는 객체이기 때문에 가능하다.

 

* 배열 생성방법 (리터럴, Array 생성자함수 사용과 차이점)

 

배열 리터럴을 사용하여 생성하는 방법

const fruits = []

fruits[0] = 'apple'
fruits[1] = 'banana'
fruits[2] = 'orange'

for(let i=0; i<fruits.length; i++){
    console.log('I like ', fruits[i])
}

배열 리터럴은 대괄호([])를 사용하여 배열을 생성하는 방법이다. 다른 프로그래밍 언어들과 다르게 배열을 선언할때 크기를 지정하지 않고, 동적으로 배열요소를 추가할 수 있다. 위 코드는 빈 배열을 먼저 생성한 다음 동적으로 배열요소를 추가하고 있다. 

const fruits = ['apple', 'banana', 'orange']

for(let i=0; i<fruits.length; i++){
    console.log('I like ', fruits[i])
}

물론 위와 같이 배열 리터럴로 선언하면서 초기값을 할당할 수 있다. 

const fruits = [,,,]

for(let i=0; i<fruits.length; i++){
    console.log('I like ', fruits[i])
}

값을 할당하지 않고 배열의 크기를 지정하려면 위와 같이 쉼표를 사용하면 된다. 쉼표 갯수만큼 배열의 크기가 설정된다.

 

Array 생성자 함수를 사용하는 방법

const fruits = new Array()

fruits[0] = 'apple'
fruits[1] = 'banana'
fruits[2] = 'orange'

for(let i=0; i<fruits.length; i++){
    console.log('I like ', fruits[i])
}

Array 생성자 함수슬 사용하여 배열을 생성하는 방법은 위와 같다. new 키워드를 사용하여 배열을 생성한다. 생성자 함수는 객체를 생성하는 함수이며 배열도 객체이기 때문에 생성자 함수로 생성할 수 있다. 

const fruits = new Array('apple', 'banana', 'orange')

for(let i=0; i<fruits.length; i++){
    console.log('I like ', fruits[i])
}

선언과 동시에 값을 할당하려면 위와 같이 생성자 함수의 인자로 할당하려는 배열요소를 넣어주면 된다. 

const fruits = new Array(3)

for(let i=0; i<fruits.length; i++){
    console.log('I like ', fruits[i])
}

빈 배열을 선언하면서 배열의 크기만 지정하려면 위와 같이 생성자 함수에 배열의 크기에 해당하는 정수값을 설정하면 된다. 

const fruits = new Array(3).fill(0)

for(let i=0; i<fruits.length; i++){
    console.log('I like ', fruits[i])
}

생성자함수로 배열을 생성하면서 크기를 지정하고 초기값을 모두 0 으로 채우려면 위와 같이 fill 메서드를 사용하면 된다. 

 

* 배열 요소 CRUD (배열요소 생성, 배열요소 조회, 배열요소 변경, 배열요소 삭제)

const movies = []

movies[0] = 'Harry Potter'
movies[1] = 'Indiana Jhones'
movies[2] = 'Jurassic Park'
movies[3] = 'Iron man'
movies[4] = 'Spider man'

배열요소를 생성하는 방법은 앞에서 언급하였기 때문에 생략하도록 한다. 

 

배열요소를 조회하는 방법은 아래와 같이 반복문을 사용하는 3가지 방법이 있다. 

const movies = []

movies[0] = 'Harry Potter'
movies[1] = 'Indiana Jhones'
movies[2] = 'Jurassic Park'
movies[3] = 'Iron man'
movies[4] = 'Spider man'

console.log('/* My Favorite Movie List */')
for(let i=0; i<movies.length; i++){
    console.log(movies[i])
}
console.log('*****************************')

가장 기본적인 반복문을 사용하여 배열을 조회하는 방법이다. 반복문 안에 var 를 사용하면 반복문으로 배열을 모두 조회한 다음에도 인덱스 값(i)이 남아있기 때문에 되도록이면 let 이나 const 를 사용하도록 한다. 

const movies = []

movies[0] = 'Harry Potter'
movies[1] = 'Indiana Jhones'
movies[2] = 'Jurassic Park'
movies[3] = 'Iron man'
movies[4] = 'Spider man'

console.log('/* My Favorite Movie List */')
for(let index in movies){
    console.log(movies[index])
}
console.log('*****************************')

for ~ in 문을 사용하는 방법이다. for ~ in 문으로 조회하는 값은 배열의 인덱스 값이다. 

const movies = []

movies[0] = 'Harry Potter'
movies[1] = 'Indiana Jhones'
movies[2] = 'Jurassic Park'
movies[3] = 'Iron man'
movies[4] = 'Spider man'

console.log('/* My Favorite Movie List */')
for(let movie of movies){
    console.log(movie)
}
console.log('*****************************')

for ~ of 문을 사용하는 방법이다. for ~ of 문으로 조회하는 값은 배열 각각의 요소이다. 

 

const movies = ['Harry Potter', 'Indiana Jhones', 'Jurassic Park', 'Iron man', 'Spider man']

movies[2] = 'Terminator'

console.log(movies)

배열의 특정요소를 변경하는 방법은 위와 같이 변경하고자 하는 배열요소의 인덱스 값을 이용하면 된다. 

 

const movies = ['Harry Potter', 'Indiana Jhones', 'Jurassic Park', 'Iron man', 'Spider man']

delete movies[2]

console.log(movies)

특정 배열요소를 삭제하려면 위와 같이 delete 키워드를 사용하면 된다. 주의할 점은 아래와 같이 삭제한 배열요소에 다른 값들이 이동하는 것이 아니라 그대로 남아있고, 해당 인덱스에 대한 값만 제거된다. 해당 값이 삭제되면서 다른 배열요소들이 이동하기 위한 방법은 추후에 설명한다.

delete 키워드를 사용한 배열요소 제거

 

 

* 배열 참조 CRUD (참조, 참조변경, 참조 삭제)

배열은 메모리의 특정 주소에 저장된다. 배열을 참조하는 방법은 아래와 같다. 

const movies = ['Harry Potter', 'Indiana Jhones', 'Jurassic Park', 'Iron man', 'Spider man']

const movies_copied = movies

console.log(movies_copied)

movies_copied 는 movies 로 가리키는 배열이 저장된 주소값을 참조한다. 하지만 자바스크립트에서 배열의 주소값에 접근하는 것은 불가능하다. 왜냐하면 자바스크립트 엔진이 동적으로 값을 부여하기 때문이다. 

const movies = ['Harry Potter', 'Indiana Jhones', 'Jurassic Park', 'Iron man', 'Spider man']
const fruits = ['apple', 'banana', 'orange']

let movies_copied = movies
movies_copied = fruits

console.log(movies_copied)

배열의 참조값을 변경하려면 위와 같이 변경하고자 하는 배열의 주소값(fruits) 을 할당해주면 된다.

let movies = ['Harry Potter', 'Indiana Jhones', 'Jurassic Park', 'Iron man', 'Spider man']

movies = null

console.log(movies)

 배열의 참조를 삭제하려면 위와 같이 null 값을 할당해주면 된다. 

 

* 배열 복사

const movies = ['Harry Potter', 'Indiana Jhones', 'Jurassic Park', 'Iron man', 'Spider man']

const movies_copied = movies

console.log(movies_copied)

먼저 앞에서 살펴본 것처럼 배열의 참조값을 다른 변수에 할당하면 된다. 

const movies = ['Harry Potter', 'Indiana Jhones', 'Jurassic Park', 'Iron man', 'Spider man']
const movies_copied = movies

movies[2] = null

console.log(movies)
console.log(movies_copied)

이렇게 하면 원본 배열에서 특정 배열요소가 변경되더라도 복사한 배열도 동일한 값을 가진다. 왜냐하면 참조하는 배열의 주소가 동일하기 때문이다. 

const movies = ['Harry Potter', 'Indiana Jhones', 'Jurassic Park', 'Iron man', 'Spider man']

const movies_copied = [...movies]

console.log(movies_copied)

자바스크립트 최신문법에서는 스프레드 연산자(...)을 사용하여 원본 배열을 복사할 수 있다. 이렇게 하면 새로운 배열이 생성되기 때문에 원본배열과 복사한 배열의 주소값은 다르다. 

const movies = ['Harry Potter', 'Indiana Jhones', 'Jurassic Park', 'Iron man', 'Spider man']
const movies_copied = [...movies]

movies[2] = null

console.log(movies)
console.log(movies_copied)

이렇게 하면 원본 배열의 특정 배열요소가 변경되더라도 복사한 배열은 원본배열과 동일하게 변경되지 않는다. 즉, 복사된 배열은 원본배열과는 독립적으로 사용가능하다. 원본 배열은 참조만 하고 복사한 배열을 변경하려고 하거나 반대로 복사한 배열은 그대로 두고 원본 배열만 변경하려면 위와 같이 하면 된다. 

const movies = ['Harry Potter', 'Indiana Jhones', 'Jurassic Park', 'Iron man', 'Spider man']
const movies_copied = movies.slice()

movies[2] = null

console.log(movies)
console.log(movies_copied)

배열의 slice 메서드를 이용해도 배열을 복사할 수 있다. 복사된 배열은 완전히 새로운 배열이기 때문에 원본배열을 변경하면 복사된 배열은 변경되지 않는다. 

 

* 문자열과 배열

const str = 'Hell world!'
console.log(str.length)

문자열도 배열이기 때문에 length 프로퍼티 값이 존재한다. 문자열의 length 값은 문자열의 길이이다. 

const str = 'Hell world!'

// 첫 번째 글자
console.log( str[0] ) // H
console.log( str.charAt(0) ) // H

// 마지막 글자
console.log( str[str.length - 1] ) // !

문자열에서 특정위치에 있는 글자를 조회하려면 위와 같이 대괄호([])를 사용하거나 charAt 메서드를 사용하면 된다. 근래에는 대괄호를 더 선호한다. charAt 은 하위 호환성을 위해 남아있다. 

const str = 'Hell world!'

console.log( str[1000] ) // undefined
console.log( str.charAt(1000) ) // '' (빈 문자열)

두 방식의 차이점은 반환할 글자가 없는 경우 드러난다. 대괄호 방식은 반환할 글자가 없을때 undefined 를 출력하고, charAt 은 빈 문자열('')을 반환한다. 

const str = 'Hello world!'
for (let char of str) {
  console.log(char) 
}

for ~ of 반복문을 사용하면 문자열을 구성하는 글자를 하나씩 조회하면서 특정 작업을 수행할 수 있다. 

let str = 'Hello world!'

str[0] = 'a' 
console.log(str)

해당 코드는 문자열의 첫번째 글자를 변경하고 있지만, 문자열은 수정이 불가능하다. 

let str = 'Hello world!'

str = 'a' 
console.log(str)

문자열 전체를 교체해야 동작한다.

console.log( 'hello world'.toUpperCase() )
console.log( 'HELLO WORLD'.toLowerCase() )

소문자를 대문자로 변경하거나, 대문자를 소문자로 변경하려면 위와 같이 하면 된다. 

console.log( "Widget".startsWith("Wid") ) // true, "Widget"은 "Wid"로 시작합니다.
console.log( "Widget".endsWith("get") ) // true, "Widget"은 "get"으로 끝납니다.

문자열이 해당 단어로 시작하는지 끝나는지 알고 싶으면 위와 같이 startsWith, endsWith 메서드를 사용하면 된다.

console.log( 'a' > 'Z' ); // true

문자열 비교시 사전순으로 비교하지만 소문자는 대문자보다 항상 크다. 아스키코드표에서 소문자가 대문자보다 크기 때문이다. 

// 글자는 같지만 케이스는 다르므로 반환되는 코드가 다릅니다.
console.log( "z".codePointAt(0) ) // 122
console.log( "Z".codePointAt(0) ) // 90

문자의 아스키코드값을 조회하려면 위와 같이 codePointAt 메서드를 사용하면 된다. 

console.log( String.fromCodePoint(90) ); // Z

반대로 해당 아스키코드 값에 대한 문자를 알아내려면 fromCodePoint 메서드를 사용하면 된다.

let str = ''

for (let i = 65; i <= 220; i++) {
  str += String.fromCodePoint(i)
}
console.log( str )
// ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„
// ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜ

해당 코드는 특정 숫자 범위안에 있는 문자를 조회하고 str 변수에 추가한다. 

 

* 연습과제 1

배열의 크기를 100으로 지정하고 모두 0 으로 초기화한 다음 3의 배수만 값이 존재하도록 해보자!

[0, 0, 3, 0, 0, 6, 0, 0, 9, ...]

위와 같이 보이면 된다. 

 

* 연습과제 2

const alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']

위 배열을 사용하여 아래와 같은 워드 피라미드를 만들어보자!

 

연습과제 3

아래와 같이 3의 배수로만 이루어진 배열을 생성해보자!

[3, 6, 9, 12, ...]

 

연습과제 4

랜덤함수를 이용하여 아래와 같이 인자로 주어진 문자 갯수만큼 랜덤한 문자열을 생성하는 프로그램을 만들어보자!

const alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']

function randomStr(n){
    // 구현하기
}

console.log(randomStr(3))
console.log(randomStr(5))
console.log(randomStr(7))

 

연습과제 5

연습과제 3의 결과로 생성된 3의 배수 배열에서 6의 배수에 해당하는 배열요소들을 찾아서 null 로 변경해보자!

 

연습문제 6

아래 코드를 이용하여 배열을 복사하고, 캡쳐화면과 같이 원본 배열을 변경하더라도 복사한 배열은 변경되지 않도록 해보자!

const movies = [
    {title: 'Harry Potter', release: '2003-02-22'}, 
    {title: 'Indiana Jhones', release: '2009-01-09'}, 
    {title: 'Jurassic Park', release: '2007-04-13'},
    {title: 'Iron man', release: '2012-12-18'},
    {title: 'Spider man', release: '2017-03-07'}
]

const movies_copied = []

// 구현하기

movies[1].title = 'syleemomo' // 원본배열 변경

console.log(movies)
console.log(movies_copied)

 

연습문제 7

아래 words 배열을 이용하여 좌우대칭인 단어의 갯수를 출력해보자!

const words = [
    'abc',
    'animal',
    'fruit',
    'abba',
    'abcba',
    'location',
    'radar',
    'madam',
    'mario',
    'level'
]

function isPalindrome(word) {
	// 구현하기
}

 

728x90