diff --git a/src/pages/list/find-unique/find-unique.service.test.ts b/src/pages/list/find-unique/find-unique.service.test.ts new file mode 100644 index 0000000..af1c2f5 --- /dev/null +++ b/src/pages/list/find-unique/find-unique.service.test.ts @@ -0,0 +1,47 @@ +import { expect, describe, it } from 'vitest'; + +import { TopItemsList } from './service'; + +describe('TopItemsList Function', () => { + test('should return unique items ignoring case sensitivity', () => { + const input = 'apple,banana,Apple,orange,Banana,apple'; + const result = TopItemsList('symbol', ',', '\n', input, true, true, false, true); + expect(result).toBe('orange'); + }); + + test('should return unique items considering case sensitivity', () => { + const input = 'apple,banana,Apple,orange,Banana,apple'; + const result = TopItemsList('symbol', ',', '\n', input, true, true, true, true); + expect(result).toBe('banana\nApple\norange\nBanana'); + }); + + test('should return all unique items ignoring case sensitivity', () => { + const input = 'apple,banana,Apple,orange,Banana,apple'; + const result = TopItemsList('symbol', ',', '\n', input, true, true, false, false); + expect(result).toBe('apple\nbanana\norange'); + }); + + test('should return all unique items considering case sensitivity', () => { + const input = 'apple,banana,Apple,orange,Banana,apple'; + const result = TopItemsList('symbol', ',', '\n', input, true, true, true, false); + expect(result).toBe('apple\nbanana\nApple\norange\nBanana'); + }); + + test('should handle empty items deletion', () => { + const input = 'apple,,banana, ,orange'; + const result = TopItemsList('symbol', ',', '\n', input, true, true, false, false); + expect(result).toBe('apple\nbanana\norange'); + }); + + test('should handle trimming items', () => { + const input = ' apple , banana , orange '; + const result = TopItemsList('symbol', ',', '\n', input, false, false, false, false); + expect(result).toBe(' apple \n banana \n orange '); + }); + + test('should handle regex split', () => { + const input = 'apple banana orange'; + const result = TopItemsList('regex', '\\s+', '\n', input, false, false, false, false); + expect(result).toBe('apple\nbanana\norange'); + }); +}); diff --git a/src/pages/list/find-unique/index.tsx b/src/pages/list/find-unique/index.tsx new file mode 100644 index 0000000..63b7b2f --- /dev/null +++ b/src/pages/list/find-unique/index.tsx @@ -0,0 +1,11 @@ +import { Box } from '@mui/material'; +import React from 'react'; +import * as Yup from 'yup'; + +const initialValues = {}; +const validationSchema = Yup.object({ + // splitSeparator: Yup.string().required('The separator is required') +}); +export default function FindUnique() { + return Lorem ipsum; +} \ No newline at end of file diff --git a/src/pages/list/find-unique/meta.ts b/src/pages/list/find-unique/meta.ts new file mode 100644 index 0000000..149ec0b --- /dev/null +++ b/src/pages/list/find-unique/meta.ts @@ -0,0 +1,13 @@ +import { defineTool } from '@tools/defineTool'; +import { lazy } from 'react'; +// import image from '@assets/text.png'; + +export const tool = defineTool('list', { + name: 'Find unique', + path: 'find-unique', + // image, + description: '', + shortDescription: '', + keywords: ['find', 'unique'], + component: lazy(() => import('./index')) +}); \ No newline at end of file diff --git a/src/pages/list/find-unique/service.ts b/src/pages/list/find-unique/service.ts new file mode 100644 index 0000000..bf35509 --- /dev/null +++ b/src/pages/list/find-unique/service.ts @@ -0,0 +1,58 @@ +export type SplitOperatorType = 'symbol' | 'regex'; + +// Function that builds the unique items array handling caseSensitive and absolutelyUnique options +function uniqueListBuilder( + array: string[], + caseSensitive: boolean, + absolutelyUnique: boolean +): string[] { + const dict: { [key: string]: number } = {}; + for (const item of array) { + const key = caseSensitive ? item : item.toLowerCase(); + dict[key] = (dict[key] || 0) + 1; + } + if (absolutelyUnique) { + for (const [key, value] of Object.entries(dict)) { + if (value > 1) { + delete dict[key]; + } + } + } + return Object.keys(dict); +} + +export function TopItemsList( + splitOperatorType: SplitOperatorType, + splitSeparator: string, + joinSeparator: string = '\n', + input: string, + deleteEmptyItems: boolean, + trimItems: boolean, + caseSensitive: boolean, + absolutelyUnique: boolean +): string { + let array: string[]; + switch (splitOperatorType) { + case 'symbol': + array = input.split(splitSeparator); + break; + case 'regex': + array = input.split(new RegExp(splitSeparator)).filter(item => item !== ''); + break; + } + + // Trim items if required + if (trimItems) { + array = array.map(item => item.trim()); + } + + // Delete empty items after initial split + if (deleteEmptyItems) { + array = array.filter(item => item !== ''); + } + + // Format the output with desired format + const uniqueListItems = uniqueListBuilder(array, caseSensitive, absolutelyUnique); + + return uniqueListItems.join(joinSeparator); +} diff --git a/src/pages/list/index.ts b/src/pages/list/index.ts index eb8c9f6..9f37390 100644 --- a/src/pages/list/index.ts +++ b/src/pages/list/index.ts @@ -1,3 +1,4 @@ +import { tool as listFindUnique } from './find-unique/meta'; import { tool as listFindMostPopular } from './find-most-popular/meta'; import { tool as listGroup } from './group/meta'; import { tool as listWrap } from './wrap/meta';