성능을 고려하는 개발자라면,
데이터를 어떻게 관리해야하는게 좋을지 고민해봐야 할 것이다.
(사실 나는 이제서야 처음으로 생각해보는 것 같다.)
JS에서 데이터를 어떻게 관리하는 것이 좋을까?
JavaScript에서 데이터를 관리하는 방법은 여러 가지가 있으며, 각 방법은 특정 상황에서 장단점이 있다.
이번 글에서는 Array, Object, Map, Set의 정의와 특징, 그리고 각각의 예시를 통해 어떻게 활용할 수 있는지 살펴보겠다.
type 정의(공통)
type NoticeItem = {
key: string;
subject: string;
content: string;
createDate: string;
createBy: string;
};
1. Array
정의
Array는 순서가 있는 데이터의 집합으로, 인덱스를 통해 각 요소에 접근할 수 있다.
JavaScript에서 배열은 동적 크기를 가지며, 다양한 데이터 타입을 포함할 수 있다.
특징
- 순서 유지: 요소가 추가된 순서대로 저장된다.
- 인덱스 접근: 0부터 시작하는 인덱스를 통해 요소에 접근할 수 있다.
- 다양한 메서드:
push
,pop
,shift
,unshift
,map
,filter
등 다양한 메서드를 제공하여 데이터 조작이 용이하다.
예시
import create from 'zustand';
const useStoreArray = create((set) => ({
notices: [] as NoticeItem[],
addNotice: (notice: NoticeItem) => set((state) => ({
notices: [...state.notices, notice],
})),
removeNotice: (key: string) => set((state) => ({
notices: state.notices.filter(notice => notice.key !== key),
})),
}));
const NoticeList: React.FC = () => {
const { notices, addNotice, removeNotice } = useStoreArray();
const handleAddNotice = () => {
const newNotice: NoticeItem = {
key: '1',
subject: '새 공지사항',
content: '공지사항 내용입니다.',
createDate: new Date().toISOString(),
createBy: '관리자',
};
addNotice(newNotice);
};
return (
<div>
<button onClick={handleAddNotice}>공지사항 추가</button>
<ul>
{notices.map(notice => (
<li key={notice.key}>
<h3>{notice.subject}</h3>
<p>{notice.content}</p>
<button onClick={() => removeNotice(notice.key)}>삭제</button>
</li>
))}
</ul>
</div>
);
};
2. Object
정의
Object는 키-값 쌍으로 데이터를 저장하는 데이터 구조로, JavaScript의 기본적인 데이터 타입 중 하나이다.
객체는 다양한 속성을 가질 수 있으며, 동적으로 속성을 추가하거나 삭제할 수 있다.
특징
- 비순서적: 키의 순서가 보장되지 않는다.
- 유연성: 다양한 데이터 타입을 값으로 가질 수 있다.
- 속성 접근: 점(.) 또는 대괄호([]) 표기법을 통해 속성에 접근할 수 있다.
예시
import create from 'zustand';
const useStoreObject = create((set) => ({
notices: {} as Record<string, NoticeItem>,
addNotice: (notice: NoticeItem) => set((state) => ({
notices: { ...state.notices, [notice.key]: notice },
})),
removeNotice: (key: string) => set((state) => {
const newNotices = { ...state.notices };
delete newNotices[key];
return { notices: newNotices };
}),
}));
const NoticeList: React.FC = () => {
const { notices, addNotice, removeNotice } = useStoreObject();
const handleAddNotice = () => {
const newNotice: NoticeItem = {
key: '1',
subject: '새 공지사항',
content: '공지사항 내용입니다.',
createDate: new Date().toISOString(),
createBy: '관리자',
};
addNotice(newNotice);
};
return (
<div>
<button onClick={handleAddNotice}>공지사항 추가</button>
<ul>
{Object.values(notices).map(notice => (
<li key={notice.key}>
<h3>{notice.subject}</h3>
<p>{notice.content}</p>
<button onClick={() => removeNotice(notice.key)}>삭제</button>
</li>
))}
</ul>
</div>
);
};
3. Map
정의
Map은 키-값 쌍으로 데이터를 저장하는 데이터 구조로, 키의 순서가 유지된다.
Map은 객체와 유사하지만, 키로 객체를 사용할 수 있으며, 다양한 메서드를 제공한다.
특징
- 순서 유지: 삽입된 순서대로 요소가 저장된다.
- 다양한 키 타입: 문자열뿐만 아니라 객체도 키로 사용할 수 있다.
- 메서드 제공:
set
,get
,delete
,has
등의 메서드를 통해 데이터 조작이 가능하다.
예시
import create from 'zustand';
const useStoreMap = create((set) => ({
notices: new Map<string, NoticeItem>(),
addNotice: (notice: NoticeItem) => set((state) => {
const newNotices = new Map(state.notices);
newNotices.set(notice.key, notice);
return { notices: newNotices };
}),
removeNotice: (key: string) => set((state) => {
const newNotices = new Map(state.notices);
newNotices.delete(key);
return { notices: newNotices };
}),
}));
const NoticeList: React.FC = () => {
const { notices, addNotice, removeNotice } = useStoreMap();
const handleAddNotice = () => {
const newNotice: NoticeItem = {
key: '1',
subject: '새 공지사항',
content: '공지사항 내용입니다.',
createDate: new Date().toISOString(),
createBy: '관리자',
};
addNotice(newNotice);
};
return (
<div>
<button onClick={handleAddNotice}>공지사항 추가</button>
<ul>
{Array.from(notices.values()).map(notice => (
<li key={notice.key}>
<h3>{notice.subject}</h3>
<p>{notice.content}</p>
<button onClick={() => removeNotice(notice.key)}>삭제</button>
</li>
))}
</ul>
</div>
);
};
4. Set
정의
Set은 중복되지 않는 값의 집합으로, 순서가 없는 데이터 구조이다.
Set은 배열과 유사하지만, 중복된 값을 허용하지 않는다.
특징
- 중복 제거: 동일한 값을 여러 번 추가할 수 없다.
- 순서 없음: 요소의 순서가 보장되지 않는다.
- 메서드 제공:
add
,delete
,has
,clear
등의 메서드를 통해 데이터 조작이 가능하다.
예시
import create from 'zustand';
const useStoreSet = create((set) => ({
notices: new Set<NoticeItem>(),
addNotice: (notice: NoticeItem) => set((state) => {
const newNotices = new Set(state.notices);
newNotices.add(notice);
return { notices: newNotices };
}),
removeNotice: (notice: NoticeItem) => set((state) => {
const newNotices = new Set(state.notices);
newNotices.delete(notice);
return { notices: newNotices };
}),
}));
const NoticeList: React.FC = () => {
const { notices, addNotice, removeNotice } = useStoreSet();
const handleAddNotice = () => {
const newNotice: NoticeItem = {
key: '1',
subject: '새 공지사항',
content: '공지사항 내용입니다.',
createDate: new Date().toISOString(),
createBy: '관리자',
};
addNotice(newNotice);
};
return (
<div>
<button onClick={handleAddNotice}>공지사항 추가</button>
<ul>
{Array.from(notices).map(notice => (
<li key={notice.key}>
<h3>{notice.subject}</h3>
<p>{notice.content}</p>
<button onClick={() => removeNotice(notice)}>삭제</button>
</li>
))}
</ul>
</div>
);
};
비교
데이터 구조 | 순서 유지 | 중복 허용 | 접근 속도 | 삽입/삭제 속도 | 적합한 사용 사례 |
---|---|---|---|---|---|
Array | O | O | O(1) | O(n) | 순서가 중요한 데이터 목록, 예: 리스트, 큐 |
Object | X | O | O(1) | O(1) | 키-값 쌍으로 데이터를 관리할 때, 예: 설정, 속성 |
Map | O | X | O(1) | O(1) | 키의 순서가 중요한 경우, 예: 캐시, 데이터베이스 레코드 |
Set | X | X | O(1) | O(1) | 중복을 허용하지 않는 데이터 집합, 예: 고유한 값 목록 |
결론
JavaScript에서 데이터를 관리하는 방법은 다양하며, 각 데이터 구조는 특정 상황에서 유용하게 사용될 수 있다.
성능을 고려할 때, 데이터의 특성과 사용 목적에 따라 적절한 데이터 구조를 선택하는 것이 중요하다.
Array는 순서가 중요한 경우에 유리하지만, 삽입과 삭제에서 성능 저하가 발생할 수 있다.
Object는 키-값 쌍으로 데이터를 관리할 때 유용하며,
Map은 키의 순서가 중요한 경우에 적합하다.
Set은 중복을 허용하지 않으면서 빠른 성능을 제공하므로, 중복된 값을 관리할 필요가 없는 경우에 유리하다.
각 데이터 구조의 장단점을 이해하고, 필요에 따라 적절한 방법을 선택하여 효율적인 데이터 관리를 할 수 있도록 하자.
(나한테 하는 말이다..ㅠ)