useIsDuplicated
배열 내 중복 여부를 판단하고 관련 유틸을 제공하는 커스텀 훅ReactTypescript
예시
검사 기준 설정
API
useIsDuplicated<T>(checkList: T[], keyExtractor?: (item: T) => string | number)- Parameters
- checkList (T[])중복 여부를 확인할 배열
- keyExtractor ((item: T) => string | number)중복 판단을 위한 키를 추출하는 함수 (선택사항)
- Returns
- isDuplicated (boolean)배열에 중복된 항목이 있는지 여부
- isDuplicatedItem (Function)특정 항목이 중복되었는지 확인하는 함수
- getNoDuplicatedList (Function)중복이 제거된 배열을 반환하는 함수
- getDuplicatedItems (Function)중복된 항목들의 배열을 반환하는 함수
개발 및 사용환경
ReactTypescript사용법
1// 기본 사용
2const items = [{ id: 1, name: 'banana' }, { id: 2, name: 'apple' }];
3const { isDuplicated, isDuplicatedItem, getNoDuplicatedList, getDuplicatedItems } = useIsDuplicated(items, (item) => item.id);
4
5// 중복 여부 확인
6console.log(isDuplicated); // false
7
8// 특정 아이템의 중복 여부 확인
9console.log(isDuplicatedItem(items[0])); // false
10
11// 중복이 제거된 배열 가져오기
12const uniqueItems = getNoDuplicatedList();
13
14// 중복된 아이템들 가져오기
15const duplicates = getDuplicatedItems();
Hook
1/**
2 * 배열 내 중복 여부를 판단하고 관련 유틸리티를 제공하는 Hook
3 *
4 * @template T - 배열의 요소 타입
5 * @param {T[]} checkList - 중복 여부를 확인할 배열
6 * @param {KeyExtractor<T>} [keyExtractor] - 중복 판단을 위한 키 추출 함수 (선택적)
7 *
8 * @returns {Object} 중복 관련 유틸리티 객체
9 * @property {boolean} isDuplicated - 배열에 중복된 요소가 있는지 여부
10 * @property {function(T): boolean} isDuplicatedItem - 특정 아이템이 중복되었는지 확인하는 함수
11 * @property {function(): T[]} getNoDuplicatedList - 중복이 제거된 배열을 반환하는 함수
12 * @property {function(): T[]} getDuplicatedItems - 중복된 요소들만 반환하는 함수
13 *
14 * @example
15 * // 기본 사용법 (item 자체를 키로 사용)
16 * const { isDuplicated } = useIsDuplicated([1, 2, 2, 3]);
17 *
18 * @example
19 * // keyExtractor 사용
20 * const { isDuplicated } = useIsDuplicated(
21 * [{ id: 1 }, { id: 2 }, { id: 2 }],
22 * (item) => item.id
23 * );
24 */
25function useIsDuplicated<T>(
26 checkList: T[],
27 keyExtractor?: (item: T) => string | number
28) {
29 const getKey =
30 keyExtractor ?? ((item: T) => item as unknown as string | number);
31
32 const { uniqueKeys, duplicates } = useMemo(() => {
33 const seen = new Set<string | number>();
34 const duplicates = new Set<string | number>();
35
36 for (const item of checkList) {
37 const key = getKey(item);
38 if (seen.has(key)) {
39 duplicates.add(key);
40 } else {
41 seen.add(key);
42 }
43 }
44
45 return { uniqueKeys: seen, duplicates };
46 }, [checkList, keyExtractor]);
47
48 const isDuplicated = checkList.length !== uniqueKeys.size;
49
50 const isDuplicatedItem = (item: T) => {
51 const key = getKey(item);
52 let count = 0;
53 for (const i of checkList) {
54 if (getKey(i) === key) {
55 count++;
56 if (count > 1) return true;
57 }
58 }
59 return false;
60 };
61
62 const getNoDuplicatedList = () => {
63 const map = new Map<string | number, T>();
64 for (const item of checkList) {
65 const key = getKey(item);
66 if (!map.has(key)) {
67 map.set(key, item);
68 }
69 }
70 return [...map.values()];
71 };
72
73 const getDuplicatedItems = () => {
74 return checkList.filter((item) => duplicates.has(getKey(item)));
75 };
76
77 return {
78 isDuplicated,
79 isDuplicatedItem,
80 getNoDuplicatedList,
81 getDuplicatedItems,
82 };
83}