From 8b58361e1fcb71823378fe71cb2abba7c716ef14 Mon Sep 17 00:00:00 2001 From: "Ibrahima G. Coulibaly" Date: Fri, 21 Jun 2024 21:59:17 +0100 Subject: [PATCH] feat: text split --- src/pages/string/split/index.tsx | 47 +++++++++++++++++++++++++++---- src/pages/string/split/service.ts | 33 ++++++++++++++++++++++ 2 files changed, 74 insertions(+), 6 deletions(-) create mode 100644 src/pages/string/split/service.ts diff --git a/src/pages/string/split/index.tsx b/src/pages/string/split/index.tsx index 0e669d8..ff04303 100644 --- a/src/pages/string/split/index.tsx +++ b/src/pages/string/split/index.tsx @@ -6,13 +6,14 @@ import Typography from '@mui/material/Typography'; import React, { useEffect, useRef, useState } from 'react'; import ToolTextInput from '../../../components/input/ToolTextInput'; 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 ToolOptions from '../../../components/ToolOptions'; +import { splitIntoChunks, splitTextByLength } from './service'; type SplitOperatorType = 'symbol' | 'regex' | 'length' | 'chunks'; const initialValues = { - splitSeparatorType: 'symbol', + splitSeparatorType: 'symbol' as SplitOperatorType, symbolValue: ' ', regexValue: '/\\s+/', lengthValue: '16', @@ -136,14 +137,47 @@ const InputWithDesc = ({ ); }; + export default function SplitText() { const [input, setInput] = useState(''); const [result, setResult] = useState(''); - const formRef = useRef>(); - useEffect(() => { - setResult(input.split(' ').join('\n')); - }, [input]); + const formRef = useRef>(null); + const FormikListenerComponent = () => { + const { values } = useFormikContext(); + 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({ // splitSeparator: Yup.string().required('The separator is required') }); @@ -174,6 +208,7 @@ export default function SplitText() { > {({ setFieldValue, values }) => ( + Split separator options {splitOperators.map(({ title, description, type }) => ( diff --git a/src/pages/string/split/service.ts b/src/pages/string/split/service.ts new file mode 100644 index 0000000..5775b79 --- /dev/null +++ b/src/pages/string/split/service.ts @@ -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; +}