diff --git a/src/pages/list/sort/service.ts b/src/pages/list/sort/service.ts index 4286ccb..4c2beb6 100644 --- a/src/pages/list/sort/service.ts +++ b/src/pages/list/sort/service.ts @@ -1,11 +1,18 @@ +import { isNumber } from "utils/string"; +export type SortingMethod = 'numeric' | 'alphabetic' | 'length'; +export type SplitOperatorType = 'symbol' | 'regex'; + // utils function that choose the way of numeric sorting mixed types of array -function customNumericSort(a: number | string, b: number | string, increasing: boolean): number { - if (typeof a === 'number' && typeof b === 'number') { - let result: number = increasing ? (a - b) : (b - a); +function customNumericSort(a: string, b: string, increasing: boolean): number { + + const formattedA = isNumber(a) ? Number(a) : a; + const formattedB = isNumber(b) ? Number(b) : b; + if (typeof formattedA === 'number' && typeof formattedB === 'number') { + let result: number = increasing ? (formattedA - formattedB) : (formattedB - formattedA); return result; - } else if (typeof a === 'string' && typeof b === 'string') { - return a.localeCompare(b); // Lexicographical comparison for strings - } else if (typeof a === 'number' && typeof b === 'string') { + } else if (typeof formattedA === 'string' && typeof formattedB === 'string') { + return formattedA.localeCompare(formattedB); // Lexicographical comparison for strings + } else if (typeof formattedA === 'number' && typeof formattedB === 'string') { return -1; // Numbers before strings } else { return 1; // Strings after numbers @@ -13,55 +20,52 @@ function customNumericSort(a: number | string, b: number | string, increasing: b } export function numericSort( - array: any[], // array we build after parsing the input + array: string[], // array we build after parsing the input increasing: boolean, - separator: string, + joinSeparator: string, removeDuplicated: boolean // the value if the checkbox has been selected 1 else 0 ) { array.sort((a, b) => customNumericSort(a, b, increasing)); if (removeDuplicated) { array = array.filter((item, index) => array.indexOf(item) === index); } - return array.join(separator); + return array.join(joinSeparator); } // utils function that choose the way of numeric sorting mixed types of array -function customLengthSort(a: number | string, b: number | string, increasing: boolean): number { - let result: number = increasing ? (a.toString().length - b.toString().length) : (b.toString().length - a.toString().length); +function customLengthSort(a: string, b: string, increasing: boolean): number { + let result: number = increasing ? (a.length - b.length) : (b.length - a.length); return result; } export function lengthSort( - array: any[], // array we build after parsing the input + array: string[], // array we build after parsing the input increasing: boolean, // select value has to be increasing for increasing order and decreasing for decreasing order - separator: string, + joinSeparator: string, removeDuplicated: boolean // the value if the checkbox has been selected 1 else 0 ) { array.sort((a, b) => customLengthSort(a, b, increasing)); if (removeDuplicated) { array = array.filter((item, index) => array.indexOf(item) === index); } - return array.join(separator); + return array.join(joinSeparator); } // Utils function that chooses the way of alphabetic sorting mixed types of array -function customAlphabeticSort(a: number | string, b: number | string, caseSensitive: boolean): number { - const stringA : string = a.toString(); - const stringB : string = b.toString(); - +function customAlphabeticSort(a: string, b: string, caseSensitive: boolean): number { if (!caseSensitive) { // Case-insensitive comparison - return stringA.toLowerCase().localeCompare(stringB.toLowerCase()); + return a.toLowerCase().localeCompare(b.toLowerCase()); } else { // Case-sensitive comparison - return stringA.charCodeAt(0) - stringB.charCodeAt(0); + return a.charCodeAt(0) - b.charCodeAt(0); } } export function alphabeticSort( - array: any[], // array we build after parsing the input + array: string[], // array we build after parsing the input increasing: boolean, // select value has to be "increasing" for increasing order and "decreasing" for decreasing order - separator: string, + joinSeparator: string, removeDuplicated: boolean, // the value if the checkbox has been selected 1 else 0 caseSensitive: boolean // the value if the checkbox has been selected 1 else 0 ) @@ -73,5 +77,40 @@ export function alphabeticSort( if (removeDuplicated) { array = array.filter((item, index) => array.indexOf(item) === index); } - return array.join(separator); + return array.join(joinSeparator); +} + +// main function +export function Sort( + sortingMethod: SortingMethod, + splitOperatorType: SplitOperatorType, + input: string, + increasing: boolean, + splitSeparator: string, + joinSeparator: string, + removeDuplicated: boolean, + caseSensitive: boolean +) { + let array: string[]; + switch(splitOperatorType) { + case 'symbol': + array = input.split(splitSeparator); + break; + case 'regex': + array = input.split(new RegExp(splitSeparator)); + break; + } + let result : string; + switch(sortingMethod) { + case 'numeric': + result = numericSort(array, increasing, joinSeparator, removeDuplicated); + break; + case 'length': + result = lengthSort(array, increasing, joinSeparator, removeDuplicated); + break; + case 'alphabetic': + result = alphabeticSort(array, increasing, joinSeparator, removeDuplicated, caseSensitive); + break; + } + return result; } \ No newline at end of file diff --git a/src/pages/list/sort/sort.service.test.ts b/src/pages/list/sort/sort.service.test.ts index d702985..0c056d8 100644 --- a/src/pages/list/sort/sort.service.test.ts +++ b/src/pages/list/sort/sort.service.test.ts @@ -1,12 +1,14 @@ // Import necessary modules and functions import { describe, it, expect } from 'vitest'; -import { alphabeticSort, lengthSort, numericSort } from './service'; -import { BlobOptions } from 'buffer'; +import { + alphabeticSort, lengthSort, numericSort, Sort, + SplitOperatorType, SortingMethod +} from './service'; // Define test cases for the numericSort function describe('numericSort function', () => { it('should sort a list in increasing order with comma separator not removeduplicated elements', () => { - const array: number[] = [9, 8, 7, 4, 2, 2, 5]; + const array: string[] = ['9', '8', '7', '4', '2', '2', '5']; const increasing: boolean = true; const separator = ', '; const removeDuplicated: boolean = false; @@ -16,7 +18,7 @@ describe('numericSort function', () => { }); it('should sort a list in decreasing order with " - " separator and remove duplicated elements', () => { - const array: number[] = [2, 4, 4, 9, 6, 6, 7]; + const array: string[] = ['2', '4', '4', '9', '6', '6', '7']; const increasing: boolean = false; const separator = ' - '; const removeDuplicated: boolean = true; @@ -27,7 +29,7 @@ describe('numericSort function', () => { }); it('should sort a list with numbers and characters and remove duplicated elements', () => { - const array: any[] = ['d','d', 'n', 'p', 'h', 'h', 6, 9, 7, 5]; + const array: string[] = ['d', 'd', 'n', 'p', 'h', 'h', '6', '9', '7', '5']; const increasing: boolean = true; const separator = ' '; const removeDuplicated: boolean = true; @@ -40,7 +42,7 @@ describe('numericSort function', () => { // Define test cases for the lengthSort function describe('lengthSort function', () => { it('should sort a list of number by length in increasing order with comma separator ', () => { - const array: number[] = [415689521, 3, 126, 12, 1523]; + const array: string[] = ['415689521', '3', '126', '12', '1523']; const increasing: boolean = true; const separator = ', '; const removeDuplicated: boolean = false; @@ -50,7 +52,7 @@ describe('numericSort function', () => { }); it('should sort a list of number by length in increasing order and remove duplicated elements ', () => { - const array: number[] = [415689521, 3, 3, 126, 12, 12, 1523]; + const array: string[] = ['415689521', '3', '3', '126', '12', '12', '1523']; const increasing: boolean = true; const separator = ', '; const removeDuplicated: boolean = true; @@ -60,7 +62,7 @@ describe('numericSort function', () => { }); it('should sort a mixed array by length in increasing order ', () => { - const array: any[] = ['ddd', 'd', 'nfg', 'p', 'h', 'h', 6555, 9, 7, 5556]; + const array: string[] = ['ddd', 'd', 'nfg', 'p', 'h', 'h', '6555', '9', '7', '5556']; const increasing: boolean = true; const separator = ' '; const removeDuplicated: boolean = true; @@ -76,7 +78,7 @@ describe('numericSort function', () => { describe('alphabeticSort function', () => { // NON CASE SENSITIVE TEST it('should sort a list of string in increasing order with comma separator ', () => { - const array: any[] = ['apple', 'pineaple', 'lemon', 'orange']; + const array: string[] = ['apple', 'pineaple', 'lemon', 'orange']; const increasing: boolean = true; const separator = ', '; const removeDuplicated: boolean = false; @@ -87,7 +89,7 @@ describe('numericSort function', () => { }); it('should sort a list of string in decreasing order with comma separator ', () => { - const array: any[] = ['apple', 'pineaple', 'lemon', 'orange']; + const array: string[] = ['apple', 'pineaple', 'lemon', 'orange']; const increasing: boolean = false; const separator = ', '; const removeDuplicated: boolean = false; @@ -98,7 +100,7 @@ describe('numericSort function', () => { }); it('should sort a list of string and symbols (uppercase and lower) in increasing order with comma separator ', () => { - const array: any[] = ['Apple', 'pineaple', 'lemon', 'Orange', 1, 9, '@', '+']; + const array: string[] = ['Apple', 'pineaple', 'lemon', 'Orange', '1', '9', '@', '+']; const increasing: boolean = true; const separator = ' '; const removeDuplicated: boolean = true; @@ -106,10 +108,10 @@ describe('numericSort function', () => { const result = alphabeticSort(array, increasing, separator, removeDuplicated, caseSensitive); expect(result).toBe('@ + 1 9 Apple lemon Orange pineaple'); - }); + }); it('should sort a list of string and symbols (uppercase and lower) in decreasing order with comma separator ', () => { - const array: any[] = ['Apple', 'pineaple', 'lemon', 'Orange', 1, 9, '@', '+']; + const array: string[] = ['Apple', 'pineaple', 'lemon', 'Orange', '1', '9', '@', '+']; const increasing: boolean = false; const separator = ' '; const removeDuplicated: boolean = true; @@ -117,12 +119,12 @@ describe('numericSort function', () => { const result = alphabeticSort(array, increasing, separator, removeDuplicated, caseSensitive); expect(result).toBe('pineaple Orange lemon Apple 9 1 + @'); - }); + }); // CASE SENSITIVE TEST it('should sort a list of string (uppercase) in decreasing order with comma separator ', () => { - const array: any[] = ['Apple', 'Pineaple', 'Lemon', 'Orange']; + const array: string[] = ['Apple', 'Pineaple', 'Lemon', 'Orange']; const increasing: boolean = false; const separator = ' '; const removeDuplicated: boolean = false; @@ -133,7 +135,7 @@ describe('numericSort function', () => { }); it('should sort a list of string (uppercase and lowercase) in increasing order with comma separator ', () => { - const array: any[] = ['Apple', 'pineaple', 'lemon', 'Orange', 1, 9]; + const array: string[] = ['Apple', 'pineaple', 'lemon', 'Orange', '1', '9']; const increasing: boolean = true; const separator = ' '; const removeDuplicated: boolean = true; @@ -141,10 +143,10 @@ describe('numericSort function', () => { const result = alphabeticSort(array, increasing, separator, removeDuplicated, caseSensitive); expect(result).toBe('1 9 Apple Orange lemon pineaple'); - }); - + }); + it('should sort a list of string (uppercase and lower) in decreasing order with comma separator ', () => { - const array: any[] = ['Apple', 'pineaple', 'lemon', 'Orange', 1, 9]; + const array: string[] = ['Apple', 'pineaple', 'lemon', 'Orange', '1', '9']; const increasing: boolean = false; const separator = ' '; const removeDuplicated: boolean = true; @@ -152,10 +154,10 @@ describe('numericSort function', () => { const result = alphabeticSort(array, increasing, separator, removeDuplicated, caseSensitive); expect(result).toBe('pineaple lemon Orange Apple 9 1'); - }); + }); it('should sort a list of string and symbols (uppercase and lower) in decreasing order with comma separator ', () => { - const array: any[] = ['Apple', 'pineaple', 'lemon', 'Orange', 1, 9, '@', '+']; + const array: string[] = ['Apple', 'pineaple', 'lemon', 'Orange', '1', '9', '@', '+']; const increasing: boolean = true; const separator = ' '; const removeDuplicated: boolean = true; @@ -166,7 +168,7 @@ describe('numericSort function', () => { }); it('should sort a list of string and symbols (uppercase and lower) in decreasing order with comma separator ', () => { - const array: any[] = ['Apple', 'pineaple', 'lemon', 'Orange', 1, 9, '@', '+']; + const array: string[] = ['Apple', 'pineaple', 'lemon', 'Orange', '1', '9', '@', '+']; const increasing: boolean = false; const separator = ' '; const removeDuplicated: boolean = true; @@ -174,10 +176,40 @@ describe('numericSort function', () => { const result = alphabeticSort(array, increasing, separator, removeDuplicated, caseSensitive); expect(result).toBe('pineaple lemon Orange Apple @ 9 1 +'); - }); + }); + }); + // Define test cases for the lengthSort function + describe('main function', () => { + it('should do everything alph', () => { + const sortingMethod: SortingMethod = 'alphabetic'; + const splitOperatorType : SplitOperatorType = 'symbol'; + const input: string = 'Apple pineaple lemon Orange 1 9 @ +'; + const increasing: boolean = true; + const splitSeparator: string = ' '; + const joinSeparator: string = ' '; + const removeDuplicated: boolean = true; + const caseSensitive: boolean = true; + const result = Sort(sortingMethod, splitOperatorType, input, increasing, splitSeparator, joinSeparator, removeDuplicated, caseSensitive); + expect(result).toBe('+ 1 9 @ Apple Orange lemon pineaple'); + }); + + it('should do everything numeric', () => { + const sortingMethod: SortingMethod = 'numeric'; + const splitOperatorType : SplitOperatorType = 'symbol'; + const input: string = '1 6 9 4 6 7 3 5 8'; + const increasing: boolean = true; + const splitSeparator: string = ' '; + const joinSeparator: string = ' '; + const removeDuplicated: boolean = true; + const caseSensitive: boolean = true; + + const result = Sort(sortingMethod, splitOperatorType, input, increasing, splitSeparator, joinSeparator, removeDuplicated, caseSensitive); + expect(result).toBe('1 3 4 5 6 7 8 9'); + }); }); + }); \ No newline at end of file diff --git a/src/utils/string.ts b/src/utils/string.ts index 7662701..785aa00 100644 --- a/src/utils/string.ts +++ b/src/utils/string.ts @@ -2,3 +2,7 @@ export function capitalizeFirstLetter(string: string | undefined) { if (!string) return ''; return string.charAt(0).toUpperCase() + string.slice(1); } + +export function isNumber(number: any) { + return !isNaN(parseFloat(number)) && isFinite(number); +} \ No newline at end of file