Bae

[TypeScript] 배열 이해하기(2) 본문

TypeScript

[TypeScript] 배열 이해하기(2)

Bae:) 2022. 4. 14. 09:51

 배열 이해하기(2)

 - 인덱스 연산자

  배열이 담고 있는 아이템 중 특정 위치에 있는 아이템을 얻고자 할 때는 인덱스 연산자(index operator)[인덱스]를 사용함

  인덱스 연산자는 배열의 특정 위치에 있는 아이템을 얻음

  다음 코드에서 05행은 numbers[index] 형태로 배열의 특정 위치(index)에 담긴 값을 얻음

// array-index-operator.ts
const numbers: number[] = [1, 2, 3, 4, 5]
for(let index = 0; index < numbers.length; index++){
	const item: number = numbers[index]
    console.log(item)	// 1 2 3 4 5
}

- 배열의 비구조화 할당

  객체뿐만 아니라 배열에도 비구조화 할당을 적용할 수 있음

  배열의 비구조화 할당문에서는 객체와 달리 [] 기호를 사용함

  다음 코드는 배열에 담긴 아이템을 비구조화 할당문으로 얻음

// array-destructuring.ts
let array: number[] = [1, 2, 3, 4, 5]
let [first, second, third, ...rest] = array
console.log(first, second, third, rest)	// 1 2 3 [4, 5]

 

- for...in 문

  ESNext 자바스크립트와 타입스크립트는 for 문을 좀 더 쉽게 사용하도록 for...in문을 제공함

  for...in문은 객체를 대상으로 사용하지만, 앞서 설명한 것처럼 배열도 객체이므로 배열에 사용할 수도 있음

for(변수 in 객체){
	...
}

  for...in문은 배열의 인덱스값을 순회함

  다음 코드는 배열에 for...in문을 사용하는 예임

// for-in.ts
let names = ['Jack', 'Jane', 'Steve']

for(let index in names){
	const name = names[index]
    	console.log(`[${index}]: ${name}`)	//[0]: Jack, [1]: Jane, [2]: Steve
}

  만약, for...in문에 객체를 사용할 때는 객체가 가진 속성(property)을 대상으로 순회함

  다음 코드는 name과 age 속성을 가진 jack 객체의 속성 이름과 값을 얻는 예임

// object-for-in.ts
let jack = {name:'Jack', age:32}
for(let property in jack)
	console.log(`${property}: ${jack[property]}`)	//name: Jack age:32

 

- for...of문

  ESNext 자바스크립트와 타입스크립트는 for...in과는 사용법이 약간 다른 for...of문도 제공함

for(let 변수 of 객체){
	...
}

  for...in문은 배열의 인덱스값을 대상으로 순회하지만, for...of문은 배열의 아이템값을 대상으로 순회함

  다음 코드는 for...of 구문의 예로, 아이템값만 필요할 때는 for...in보다 좀 더 간결하게 구현할 수 있음

// for-of.ts
for(let name of ['Jack', 'Jane', 'Steve'])
	console.log(name)	// Jack Jane Steve

 

- 제너릭 방식 타입

  배열을 다루는 함수를 작성할 때는 number[]와 같이 타입이 고정된 함수를 만들기보다는 T[] 형태로 배열의 아이템 타입을 한꺼번에 표현하는 것이 편리함

  타입을 T와 같은 일종의 변수(타입 변수)로 취급하는 것을 제너릭(generics)타입 이라고 함

  이제 자바스크립트 함수에는 타입스크립트의 제너릭 타입을 사용하는 방법을 알아보겠음

  다음 arrayLength 함수는 배열의 길이를 얻는 함수로서 자바스크립트로 구현되었음

const arrayLength = (array) => array.length

  이 함수가 number[], string[], IPerson[] 등 다양한 아이템 타입을 가지는 배열에 똑같이 적용되게 하려면 다음처럼 배열의 타입 주석을 T[]로 표현함

const arrayLength = (array: T[]): number => array.length

  그런데 이렇게 하면 컴파일러가 T의 의미를 알 수 있어야 함

  즉, T가 타입 변수(type variable)라고 알려줘야 함

  예를 들어, 배열의 길이를 구하는 함수와 배열이 비었는지를 판별하는 함수를 제네릭 함수 스타일로 구현하면 다음과 같음

export const arrayLength = <T>(array: T[]): number => array.length
export const isEmpty = <T>(array: T[]): boolean => arrayLength<T>(array) == 0

  다음 코드는 앞서 배열의 타입 절에서 본 array-type.ts의 코드에 위 두 함수를 적용한 예임

  제네릭 함수로 구현했으므로 다양한 배열 타입에 모두 정상적으로 대응하는 것을 볼 수 있음

// arrayLength-test.ts
import {arrayLength, isEmpty} from './arrayLength'
let numArray: number[] = [1, 2, 3]
let strArray: string[] = ['Hello', 'Wolrd']

type IPerson = {name: string, age?: number}
let personArray: IPerson[] = [{name:'Jack'},{name:'Jane', age:32}]

console.log(
	arrayLength(numArray)	// 3
    	arrayLength(strArray)	// 2
    	arrayLength(personArray)	// 2
    	isEmpty([]),	//true
    	isEmpty([1])	//false
)

 

- 제네릭 함수의 타입 추론

  다음 코드에서 01행의 identity 함수는 제네릭 형태로 구현되었음

// generic-type-inference.ts
const identity = <T>(n: T): T => n
console.log(
	identity<boolean>(true),	// true
    identity(true)		// true
)

  제네릭 형태로 구현된 함수는 원칙적으로는 03행처럼 타입 변수를 다음과 같은 형태로 명시해 주어야 함

함수 이름<타입 변수>(매개 변수)

  하지만 이런 코드는 번거로워서 타입스크립트는 04행처럼 타입 변수 부분을 생략할 수 있게 함

  타입스크립트는 타입 변수가 생략된 제네릭 함수를 만나면 타입 추론을 통해 생략된 타입을 찾아냄

 

- 전개 연산자

  전개 연산자는 배열에도 적용할 수 있음

  다음 코드는 전개 연산자를 사용해 두 배열과 특정 값을 동시에 결합하는 예임

// spread-operator.ts
let array1: number[] = [1]
let array2: number[] = [2, 3]
let mergedArray: number[] = [...array1, ...array2, 4]
console.log(mergedArray)	// [1, 2, 3,4]

 

- range 함수 구현

  배열에 전개 연산자를 적용하면 R.range와 같은 함수를 쉽게 만들 수 있음

  다음 range 함수는 재귀 함수(recursive function) 스타일로 동작하며, R.range처럼 from에서 to까지 수로 구성된 배열을 생성해 줌

// range.ts
export const range = (from: number, to: number): number[] =>
	from < to ? [from, ...range(from + 1, to)]: []

 

  다음은 range 하뭇가 정상적으로 동작하는지 알아보는 테스트 코드임

  range 함수에 1과 9+1을 전달했으므로 1부터 9까지 수로 구성된 배열을 반환함

import {range} from './range'
let numbers: number[] = range(1, 9+1)
console.log(numbers)	//[1, 2, 3, 4, 5, 6, 7, 8, 9]

 

[출처: Do it 타입스크립트 프로그래밍]

Comments