1
0
mirror of https://github.com/robonen/lorem-blog.git synced 2026-03-20 10:54:38 +00:00

feat(utils): add utility functions for reading time, date formatting, pluralization, and KMP search

This commit is contained in:
2025-06-14 15:35:26 +07:00
parent 092e8a320e
commit 2c6b5be279

172
src/shared/utils.ts Normal file
View File

@@ -0,0 +1,172 @@
/**
* @name calculateReadingTime
* @description Calculates the reading time for a given content based on an average reading speed of 200 words per minute.
*
* @param {string} content - The content for which to calculate the reading time.
* @returns {number} The estimated reading time in minutes, rounded up to the nearest whole number.
*
* @example
* const time = calculateReadingTime("This is a sample content to test the reading time calculation.");
* console.log(time); // Outputs: 1
*/
export function calculateReadingTime(content: string) {
const wordsPerMinute = 200;
const words = content.split(/\s+/).length;
return Math.ceil(words / wordsPerMinute);
}
/**
* @name formatDate
* @description Formats a date string into a more readable format.
*
* @param {string} dateString - The date string to format.
* @returns {string} The formatted date string in the format "dd MMMM".
*
* @example
* const formattedDate = formatDate("2023-10-01T12:00:00Z");
* console.log(formattedDate); // Outputs: "9 Apr"
*/
export function formatDate(dateString: string) {
const date = new Date(dateString);
const month = date.toLocaleDateString('ru-RU', {
month: 'short',
});
return `${date.getDate()} ${month.charAt(0).toUpperCase() + month.slice(1, -1)}`;
}
/**
* @name formatDateTime
* @description Formats a date string into a more readable format with time.
*
* @param {string} dateString - The date string to format.
* @returns {string} The formatted date string in the format "dd.MMMM.yyyy в HH:mm".
*
* @example
* const formattedDateTime = formatDateTime("2023-10-01T12:00:00Z");
* console.log(formattedDateTime); // Outputs: "1.04.2025 в 12:00"
*/
export function formatDateTime(dateString: string) {
const date = new Date(dateString);
const onlyDate = date.toLocaleDateString('ru-RU', {
year: 'numeric',
month: 'numeric',
day: 'numeric',
});
const time = date.toLocaleTimeString('ru-RU', {
hour: '2-digit',
minute: '2-digit',
});
return `${onlyDate} в ${time}`;
}
/**
* @name pluralize
* @description Returns a pluralized form of a word based on the count.
*
* @param {number} count - The count to determine the pluralization.
* @param {string[]} forms - An array containing the singular, plural, and genitive forms of the word.
* @returns {string} The appropriate form of the word based on the count.
*
* @example
* const word = pluralize(1, ['яблоко', 'яблока', 'яблок']);
* console.log(word); // Outputs: "яблоко"
*/
export function pluralize(count: number, forms: string[]) {
const [singular, plural, genitive] = forms;
if (count === 1)
return singular;
if (count > 1 && count < 5)
return plural;
return genitive;
}
/**
* @name computeLPS
* @description Computes the Longest Prefix Suffix (LPS) array for the KMP algorithm.
*
* @param {string} pattern - The pattern for which to compute the LPS array.
* @returns {number[]} The LPS array where lps[i] is the length of the longest proper prefix which is also a suffix for the substring pattern[0..i].
*
* @example
* const lps = computeLPS("ABABAC");
* console.log(lps); // Outputs: [0, 0, 1, 2, 0, 1]
*/
function computeLPS(pattern: string) {
const lps = Array.from<number>({ length: pattern.length }).fill(0);
let len = 0;
let i = 1;
while (i < pattern.length) {
if (pattern[i] === pattern[len]) {
len++;
lps[i] = len;
i++;
}
else {
if (len !== 0) {
len = lps[len - 1]!;
}
else {
lps[i] = 0;
i++;
}
}
}
return lps;
}
/**
* @name kmpSearch
* @description Implements the Knuth-Morris-Pratt (KMP) algorithm for substring search.
*
* @param {string} text - The text in which to search for the pattern.
* @param {string} pattern - The pattern to search for in the text.
* @returns {boolean} Returns true if the pattern is found in the text, otherwise false.
*
* @example
* const found = kmpSearch("hello world", "world");
* console.log(found); // Outputs: true
*/
export function kmpSearch(text: string, pattern: string) {
if (pattern.length === 0)
return true;
if (text.length === 0)
return false;
const textLower = text.toLowerCase();
const patternLower = pattern.toLowerCase();
const lps = computeLPS(patternLower);
let i = 0; // index for text
let j = 0; // index for pattern
while (i < textLower.length) {
if (patternLower[j] === textLower[i]) {
i++;
j++;
}
if (j === patternLower.length) {
return true; // Found match
}
else if (i < textLower.length && patternLower[j] !== textLower[i]) {
if (j !== 0) {
j = lps[j - 1]!;
}
else {
i++;
}
}
}
return false;
}