mirror of
https://github.com/iib0011/omni-tools.git
synced 2025-09-19 05:59:34 +02:00
feat: text split
This commit is contained in:
@@ -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 }) => (
|
||||||
|
33
src/pages/string/split/service.ts
Normal file
33
src/pages/string/split/service.ts
Normal 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;
|
||||||
|
}
|
Reference in New Issue
Block a user