diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 1f5fb72..57c0481 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -4,11 +4,10 @@
-
-
+
-
-
+
+
@@ -204,15 +203,7 @@
-
-
-
-
- 1719172147719
-
-
-
- 1719172147719
+
@@ -598,7 +589,15 @@
1719600739052
-
+
+
+ 1720545582958
+
+
+
+ 1720545582958
+
+
@@ -642,7 +641,6 @@
-
@@ -667,7 +665,8 @@
-
+
+
diff --git a/src/pages/list/find-most-popular/index.tsx b/src/pages/list/find-most-popular/index.tsx
index 40566cf..6d5da58 100644
--- a/src/pages/list/find-most-popular/index.tsx
+++ b/src/pages/list/find-most-popular/index.tsx
@@ -1,11 +1,172 @@
import { Box } from '@mui/material';
-import React from 'react';
+import React, { useState } from 'react';
+import ToolTextInput from '../../../components/input/ToolTextInput';
+import ToolTextResult from '../../../components/result/ToolTextResult';
import * as Yup from 'yup';
+import ToolOptions from '../../../components/options/ToolOptions';
+import {
+ DisplayFormat,
+ SortingMethod,
+ SplitOperatorType,
+ TopItemsList
+} from './service';
+import ToolInputAndResult from '../../../components/ToolInputAndResult';
+import SimpleRadio from '../../../components/options/SimpleRadio';
+import TextFieldWithDesc from '../../../components/options/TextFieldWithDesc';
+import CheckboxWithDesc from '../../../components/options/CheckboxWithDesc';
+import SelectWithDesc from '../../../components/options/SelectWithDesc';
+
+const initialValues = {
+ splitSeparatorType: 'symbol' as SplitOperatorType,
+ sortingMethod: 'alphabetic' as SortingMethod,
+ displayFormat: 'count' as DisplayFormat,
+ splitSeparator: ',',
+ deleteEmptyItems: false,
+ ignoreItemCase: false,
+ trimItems: false
+};
+const splitOperators: {
+ title: string;
+ description: string;
+ type: SplitOperatorType;
+}[] = [
+ {
+ title: 'Use a Symbol for Splitting',
+ description: 'Delimit input list items with a character.',
+ type: 'symbol'
+ },
+ {
+ title: 'Use a Regex for Splitting',
+ type: 'regex',
+ description: 'Delimit input list items with a regular expression.'
+ }
+];
-const initialValues = {};
-const validationSchema = Yup.object({
- // splitSeparator: Yup.string().required('The separator is required')
-});
export default function FindMostPopular() {
- return Lorem ipsum;
-}
\ No newline at end of file
+ const [input, setInput] = useState('');
+ const [result, setResult] = useState('');
+ const compute = (optionsValues: typeof initialValues, input: any) => {
+ const {
+ splitSeparatorType,
+ splitSeparator,
+ displayFormat,
+ sortingMethod,
+ deleteEmptyItems,
+ ignoreItemCase,
+ trimItems
+ } = optionsValues;
+
+ setResult(
+ TopItemsList(
+ splitSeparatorType,
+ sortingMethod,
+ displayFormat,
+ splitSeparator,
+ input,
+ deleteEmptyItems,
+ ignoreItemCase,
+ trimItems
+ )
+ );
+ };
+ const validationSchema = Yup.object({
+ // splitSeparator: Yup.string().required('The separator is required')
+ });
+
+ return (
+
+
+ }
+ result={}
+ />
+ [
+ {
+ title: 'How to Extract List Items?',
+ component: (
+
+ {splitOperators.map(({ title, description, type }) => (
+ updateField('splitSeparatorType', type)}
+ title={title}
+ description={description}
+ checked={values.splitSeparatorType === type}
+ />
+ ))}
+ updateField('splitSeparator', val)}
+ />
+
+ )
+ },
+ {
+ title: 'Item comparison',
+ component: (
+
+ updateField('deleteEmptyItems', value)}
+ />
+ updateField('trimItems', value)}
+ />
+ updateField('ignoreItemCase', value)}
+ />
+
+ )
+ },
+ {
+ title: 'Top item output format',
+ component: (
+
+ updateField('displayFormat', value)}
+ description={'How to display the most popular list items?'}
+ />
+ updateField('sortingMethod', value)}
+ description={'Select a sorting method.'}
+ />
+
+ )
+ }
+ ]}
+ initialValues={initialValues}
+ input={input}
+ validationSchema={validationSchema}
+ />
+
+ );
+}
diff --git a/src/pages/list/find-most-popular/service.ts b/src/pages/list/find-most-popular/service.ts
index 3c812b9..fd6e6fa 100644
--- a/src/pages/list/find-most-popular/service.ts
+++ b/src/pages/list/find-most-popular/service.ts
@@ -3,105 +3,112 @@ export type DisplayFormat = 'count' | 'percentage' | 'total';
export type SortingMethod = 'count' | 'alphabetic';
// Function that takes the array as arg and returns a dict of element occurrences and handle the ignoreItemCase
-function dictMaker(array: string[],
- ignoreItemCase: boolean
+function dictMaker(
+ array: string[],
+ ignoreItemCase: boolean
): { [key: string]: number } {
- const dict: { [key: string]: number } = {};
- for (const item of array) {
- const key = ignoreItemCase ? item.toLowerCase() : item;
- dict[key] = (dict[key] || 0) + 1;
- }
- return dict;
+ const dict: { [key: string]: number } = {};
+ for (const item of array) {
+ const key = ignoreItemCase ? item.toLowerCase() : item;
+ dict[key] = (dict[key] || 0) + 1;
+ }
+ return dict;
}
// Function that sorts the dict created with dictMaker based on the chosen sorting method
function dictSorter(
- dict: { [key: string]: number },
- sortingMethod: SortingMethod,
+ dict: { [key: string]: number },
+ sortingMethod: SortingMethod
): { [key: string]: number } {
- let sortedArray: [string, number][];
- switch (sortingMethod) {
- case 'count':
- sortedArray = Object.entries(dict).sort(([, countA], [, countB]) => countB - countA);
- break;
- case 'alphabetic':
- sortedArray = Object.entries(dict).sort(([keyA], [keyB]) => {
- return keyA.localeCompare(keyB)
- });
- break;
- default:
- sortedArray = Object.entries(dict);
- break;
- }
- return Object.fromEntries(sortedArray);
+ let sortedArray: [string, number][];
+ switch (sortingMethod) {
+ case 'count':
+ sortedArray = Object.entries(dict).sort(
+ ([, countA], [, countB]) => countB - countA
+ );
+ break;
+ case 'alphabetic':
+ sortedArray = Object.entries(dict).sort(([keyA], [keyB]) => {
+ return keyA.localeCompare(keyB);
+ });
+ break;
+ default:
+ sortedArray = Object.entries(dict);
+ break;
+ }
+ return Object.fromEntries(sortedArray);
}
// Function that prepares the output of dictSorter based on the chosen display format
function displayFormater(
- dict: { [key: string]: number },
- displayFormat: DisplayFormat
+ dict: { [key: string]: number },
+ displayFormat: DisplayFormat
): string[] {
- let formattedOutput: string[] = [];
- const total = Object.values(dict).reduce((acc, val) => acc + val, 0);
+ let formattedOutput: string[] = [];
+ const total = Object.values(dict).reduce((acc, val) => acc + val, 0);
- switch (displayFormat) {
- case 'percentage':
- Object.entries(dict).forEach(([key, value]) => {
- formattedOutput.push(`${key}: ${value} (${((value / total) * 100).toFixed(2)}%)`);
- });
- break;
- case "total":
- Object.entries(dict).forEach(([key, value]) => {
- formattedOutput.push(`${key}: ${value} (${value} / ${total})`);
- });
- break;
- case "count":
- Object.entries(dict).forEach(([key, value]) => {
- formattedOutput.push(`${key}: ${value}`);
- });
- break;
- }
- return formattedOutput;
+ switch (displayFormat) {
+ case 'percentage':
+ Object.entries(dict).forEach(([key, value]) => {
+ formattedOutput.push(
+ `${key}: ${value} (${((value / total) * 100).toFixed(2)}%)`
+ );
+ });
+ break;
+ case 'total':
+ Object.entries(dict).forEach(([key, value]) => {
+ formattedOutput.push(`${key}: ${value} (${value} / ${total})`);
+ });
+ break;
+ case 'count':
+ Object.entries(dict).forEach(([key, value]) => {
+ formattedOutput.push(`${key}: ${value}`);
+ });
+ break;
+ }
+ return formattedOutput;
}
export function TopItemsList(
- splitOperatorType: SplitOperatorType,
- sortingMethod: SortingMethod,
- displayFormat: DisplayFormat,
- splitSeparator: string,
- input: string,
- deleteEmptyItems: boolean,
- ignoreItemCase: boolean,
- trimItems: boolean
+ splitOperatorType: SplitOperatorType,
+ sortingMethod: SortingMethod,
+ displayFormat: DisplayFormat,
+ splitSeparator: string,
+ input: string,
+ deleteEmptyItems: boolean,
+ ignoreItemCase: boolean,
+ trimItems: 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;
- }
+ 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());
- }
+ // 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 !== '');
- }
+ // Delete empty items after initial split
+ if (deleteEmptyItems) {
+ array = array.filter((item) => item !== '');
+ }
- // Transform the array into dict
- const unsortedDict = dictMaker(array, ignoreItemCase);
+ // Transform the array into dict
+ const unsortedDict = dictMaker(array, ignoreItemCase);
- // Sort the list if required
- const sortedDict = dictSorter(unsortedDict, sortingMethod);
+ // Sort the list if required
+ const sortedDict = dictSorter(unsortedDict, sortingMethod);
- // Format the output with desired format
- const formattedOutput = displayFormater(sortedDict, displayFormat);
+ // Format the output with desired format
+ const formattedOutput = displayFormater(sortedDict, displayFormat);
- return formattedOutput.join('\n');
+ return formattedOutput.join('\n');
}
diff --git a/src/pages/list/sort/index.tsx b/src/pages/list/sort/index.tsx
index ab1a6d2..d4d345a 100644
--- a/src/pages/list/sort/index.tsx
+++ b/src/pages/list/sort/index.tsx
@@ -40,8 +40,7 @@ const splitOperators: {
export default function SplitText() {
const [input, setInput] = useState('');
const [result, setResult] = useState('');
- // const formRef = useRef>(null);
- const computeExternal = (optionsValues: typeof initialValues, input: any) => {
+ const compute = (optionsValues: typeof initialValues, input: any) => {
const {
splitSeparatorType,
joinSeparator,
@@ -82,7 +81,7 @@ export default function SplitText() {
result={}
/>
[
{
title: 'Input item separator',