41 lines
1.3 KiB
TypeScript
41 lines
1.3 KiB
TypeScript
/** pick up to random N elements from array.
|
||
* just shuffle it if N is unspecified or greater than the length of the array.
|
||
* the original array remains unmodified. */
|
||
export function sample<T>(arr: T[], n: number = arr.length): T[] {
|
||
if (n > arr.length) return sample(arr, arr.length);
|
||
const copy = [...arr];
|
||
for (let i = 0; i < n; i++) {
|
||
const j = i + Math.floor(Math.random() * (copy.length - i));
|
||
[copy[i], copy[j]] = [copy[j] as T, copy[i] as T];
|
||
}
|
||
return copy.slice(0, n);
|
||
}
|
||
|
||
/** sleep for N milliseconds */
|
||
export const sleep = (msec: number) =>
|
||
new Promise((resolve) => setTimeout(resolve, msec));
|
||
|
||
/** normalize user-visible text and neutralize accidental mentions/tags */
|
||
export const sanitizeText = (text: string) =>
|
||
text
|
||
.replaceAll(/\r\n?/g, "\n")
|
||
.replaceAll(/\n[\t ]+/g, "\n")
|
||
.replaceAll(/\n{3,}/g, "\n\n")
|
||
.trim()
|
||
.replaceAll("@", "@")
|
||
.replaceAll("#", "#");
|
||
|
||
const POLITE_ENDING =
|
||
/(?:です|ます|ません|でした|ました|でしょう|ください)(?:ね|よ|か)?$/u;
|
||
|
||
export function isPoliteEnough(text: string) {
|
||
const sentences = text
|
||
.split(/[。!?]+/u)
|
||
.map((sentence) => sentence.trim())
|
||
.filter(Boolean);
|
||
return (
|
||
sentences.length > 0 &&
|
||
sentences.some((sentence) => POLITE_ENDING.test(sentence))
|
||
);
|
||
}
|