feat: text split

This commit is contained in:
Ibrahima G. Coulibaly
2024-06-21 21:59:17 +01:00
parent 4b8ba1f17c
commit 8b58361e1f
2 changed files with 74 additions and 6 deletions

View File

@@ -6,13 +6,14 @@ import Typography from '@mui/material/Typography';
import React, { useEffect, useRef, useState } from 'react'; import React, { useEffect, useRef, useState } from 'react';
import ToolTextInput from '../../../components/input/ToolTextInput'; import ToolTextInput from '../../../components/input/ToolTextInput';
import ToolTextResult from '../../../components/result/ToolTextResult'; import ToolTextResult from '../../../components/result/ToolTextResult';
import { Field, Formik, FormikProps } from 'formik'; import { Field, Formik, FormikProps, useFormikContext } from 'formik';
import * as Yup from 'yup'; import * as Yup from 'yup';
import ToolOptions from '../../../components/ToolOptions'; import ToolOptions from '../../../components/ToolOptions';
import { splitIntoChunks, splitTextByLength } from './service';
type SplitOperatorType = 'symbol' | 'regex' | 'length' | 'chunks'; type SplitOperatorType = 'symbol' | 'regex' | 'length' | 'chunks';
const initialValues = { const initialValues = {
splitSeparatorType: 'symbol', splitSeparatorType: 'symbol' as SplitOperatorType,
symbolValue: ' ', symbolValue: ' ',
regexValue: '/\\s+/', regexValue: '/\\s+/',
lengthValue: '16', lengthValue: '16',
@@ -136,14 +137,47 @@ const InputWithDesc = ({
</Box> </Box>
); );
}; };
export default function SplitText() { export default function SplitText() {
const [input, setInput] = useState<string>(''); const [input, setInput] = useState<string>('');
const [result, setResult] = useState<string>(''); const [result, setResult] = useState<string>('');
const formRef = useRef<FormikProps<typeof initialValues>>(); const formRef = useRef<FormikProps<typeof initialValues>>(null);
useEffect(() => { const FormikListenerComponent = () => {
setResult(input.split(' ').join('\n')); const { values } = useFormikContext<typeof initialValues>();
}, [input]);
useEffect(() => {
const {
splitSeparatorType,
outputSeparator,
charBeforeChunk,
charAfterChunk,
chunksValue,
symbolValue,
regexValue,
lengthValue
} = values;
let splitText;
switch (splitSeparatorType) {
case 'symbol':
splitText = input.split(symbolValue);
break;
case 'regex':
splitText = input.split(new RegExp(regexValue));
break;
case 'length':
splitText = splitTextByLength(input, Number(lengthValue));
break;
case 'chunks':
splitText = splitIntoChunks(input, Number(chunksValue)).map(
(chunk) => `${charBeforeChunk}${chunk}${charAfterChunk}`
);
}
const res = splitText.join(outputSeparator);
setResult(res);
}, [values, input]);
return null; // This component doesn't render anything
};
const validationSchema = Yup.object({ const validationSchema = Yup.object({
// splitSeparator: Yup.string().required('The separator is required') // splitSeparator: Yup.string().required('The separator is required')
}); });
@@ -174,6 +208,7 @@ export default function SplitText() {
> >
{({ setFieldValue, values }) => ( {({ setFieldValue, values }) => (
<Stack direction={'row'} spacing={2}> <Stack direction={'row'} spacing={2}>
<FormikListenerComponent />
<Box> <Box>
<Typography fontSize={22}>Split separator options</Typography> <Typography fontSize={22}>Split separator options</Typography>
{splitOperators.map(({ title, description, type }) => ( {splitOperators.map(({ title, description, type }) => (

View File

@@ -0,0 +1,33 @@
export function splitTextByLength(text: string, length: number) {
if (length <= 0) throw new Error('Length must be a positive number');
const result: string[] = [];
for (let i = 0; i < text.length; i += length) {
result.push(text.slice(i, i + length));
}
return result;
}
export function splitIntoChunks(text: string, numChunks: number) {
if (numChunks <= 0)
throw new Error('Number of chunks must be a positive number');
const totalLength = text.length;
if (totalLength < numChunks)
throw new Error(
'Text length must be at least as long as the number of chunks'
);
const chunkSize = Math.ceil(totalLength / numChunks); // Calculate the chunk size, rounding up to handle remainders
let result = [];
for (let i = 0; i < totalLength; i += chunkSize) {
result.push(text.slice(i, i + chunkSize));
}
// Ensure the result contains exactly numChunks, adjusting the last chunk if necessary
if (result.length > numChunks) {
result[numChunks - 1] = result.slice(numChunks - 1).join(''); // Merge any extra chunks into the last chunk
result = result.slice(0, numChunks); // Take only the first numChunks chunks
}
return result;
}