JavaScript/TypeScript에서 튜플(Tuple) 이해하기
튜플이란?
튜플은 여러 값을 하나의 단위로 묶은 구조입니다. 배열과 비슷하지만, 각 위치의 의미가 고정되어 있습니다.
일상 예시로 이해하기
배열은 "물건을 담는 상자"라면, 튜플은 "각 칸의 의미가 정해진 상자"입니다.예를 들어:
- 일반 배열: ['사과', '바나나', '오렌지'] - 모두 과일
- 튜플: ['홍길동', 25, '서울'] - [이름, 나이, 주소]로 의미가 고정
JavaScript에서 튜플의 모습
JavaScript에는 튜플 타입이 없지만, 배열을 튜플처럼 사용할 수 있습니다.
예시 1: 좌표
// 일반 배열
const coordinate
예시 2: 사용자 정보
// [이름, 나이, 이메일] 형태로 고정
const userInfo = ['김철수', 30, 'kim@example.com'];
const name = userInfo[0]; // '김철수'
const age = userInfo[1]; // 30
const email = userInfo[2]; // 'kim@example.com'
Map과 튜플
Map을 순회할 때 튜플 형태가 자동으로 반환됩니다.
// 학생들의 점수를 저장하는 Map
const studentScores = new Map();
studentScores.set('철수', [90, 85, 95]);
studentScores.set('영희', [88, 92, 87]);
studentScores.set('민수', [95, 90, 93]);
// Map을 순회하면 [key, value] 형태의 튜플이 반환됩니다
for (const entry of studentScores) {
console.log(entry);
// 출력: ['철수', [90, 85, 95]]
// ['영희', [88, 92, 87]]
// ['민수', [95, 90, 93]]
// entry는 [key, value] 튜플입니다
const studentName = entry[0]; // '철수'
const scores = entry[1]; // [90, 85, 95]
}
구조 분해 할당으로 더 쉽게
for (const [studentName, scores] of studentScores) {
console.log(`${studentName}의 점수:`, scores);
// 출력: 철수의 점수: [90, 85, 95]
// 영희의 점수: [88, 92, 87]
// 민수의 점수: [95, 90, 93]
}
튜플 vs 일반 배열
일반 배열
const fruits = ['사과', '바나나', '오렌지'];
// 모든 요소가 같은 의미 (과일)
// 순서가 바뀌어도 문제없음
튜플
const person = ['홍길동', 25, '서울'];
// 각 위치의 의미가 고정됨: [이름, 나이, 주소]
// 순서가 바뀌면 의미가 달라짐!
실전 예시: filter() 사용 시 주의사항
튜플에 filter()를 사용할 때 주의가 필요합니다.
const studentScores = new Map();
studentScores.set('철수', [90, 85, 95]);
studentScores.set('영희', [88, 92, 87]);
for (const entry of studentScores) {
// entry는 ['철수', [90, 85, 95]] 형태의 튜플
// ❌ 잘못된 방법
const wrong = entry.filter((item) => item === '철수');
// 결과: ['철수'] - 키만 반환됨
// ✅ 올바른 방법
const studentName = entry[0]; // '철수'
const scores = entry[1]; // [90, 85, 95]
if (studentName === '철수') {
console.log('철수의 점수:', scores);
}
}
TypeScript에서의 튜플
TypeScript는 튜플 타입을 지원합니다.
// 튜플 타입 선언
type UserInfo = [string, number, string]; // [이름, 나이, 이메일]
const user: UserInfo = ['김철수', 30, 'kim@example.com'];
// 타입 안정성 보장
const name: string = user[0]; // ✅ OK
const age: number = user[1]; // ✅ OK
const email: string = user[2]; // ✅ OK
정리
- 튜플은 각 위치의 의미가 고정된 배열입니다.
- JavaScript에서는 배열을 튜플처럼 사용할 수 있습니다.
- Map을 순회하면 [key, value] 튜플이 반환됩니다.
- 구조 분해 할당으로 더 읽기 쉽게 사용할 수 있습니다.
- 튜플에 filter()를 사용할 때는 구조를 고려해야 합니다.
튜플은 데이터 구조를 명확하게 표현하는 데 유용합니다. Map을 다룰 때 자주 마주치게 되니, 이 개념을 이해하면 코드를 더 잘 이해할 수 있습니다.
튜플이 나타나는 다양한 상황
1. 함수에서 여러 값 반환
// 함수가 여러 값을 반환할 때
function getUserInfo() {
return ['홍길동', 25, '서울']; // [이름, 나이, 주소] 튜플
}
const [name, age, city] = getUserInfo();
2. 배열 메서드의 반환값
const fruits = ['사과', '바나나', '오렌지'];
// findIndex는 인덱스를 반환하지만, 값도 함께 필요할 때
const index = fruits.findIndex(fruit => fruit === '바나나');
const value = fruits[index];
// 또는 튜플로 만들기
const result = [index, fruits[index]]; // [1, '바나나']
3. Object.entries()
const person = {
name: '김철수',
age: 30,
city: '서울'
};
// Object.entries()도 [key, value] 튜플을 반환합니다
for (const [key, value] of Object.entries(person)) {
console.log(key, value);
// name 김철수
// age 30
// city 서울
}
4. 직접 만든 튜플
// 좌표를 튜플로 표현
const point1 = [10, 20]; // [x, y]
const point2 = [30, 40];
// 두 점 사이의 거리 계산
function getDistance([x1, y1], [x2, y2]) {
return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
}
const distance = getDistance(point1, point2);
5. Set의 entries()도 튜플 반환
const mySet = new Set(['사과', '바나나', '오렌지']);
// Set.entries()도 [value, value] 튜플을 반환합니다
for (const [value1, value2] of mySet.entries()) {
console.log(value1, value2);
// 사과 사과
// 바나나 바나나
// 오렌지 오렌지
}
6. Promise.all()의 결과
const promise1 = Promise.resolve('첫 번째');
const promise2 = Promise.resolve('두 번째');
const promise3 = Promise.resolve('세 번째');
Promise.all([promise1, promise2, promise3])
.then(([result1, result2, result3]) => {
// 결과가 튜플 형태로 반환됩니다
console.log(result1, result2, result3);
});
정리
튜플은:
- JavaScript/TypeScript에서 배열로 표현됩니다
Map을 순회할 때 [key, value] 튜플이 반환되는 것은 Map의 동작 방식일 뿐, 튜플 자체는 더 넓은 개념입니다.