js_anki: prettier-format string.json
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
Pre-commit checks / pre-commit (${{ matrix.group }}) (mypy, mypy) (push) Waiting to run
Pre-commit checks / pre-commit (${{ matrix.group }}) (pylint, pylint) (push) Waiting to run
Pre-commit checks / pre-commit (${{ matrix.group }}) (rest, ) (push) Waiting to run
Pre-commit checks / pre-commit (${{ matrix.group }}) (shellcheck, shellcheck) (push) Waiting to run
Python tests / test (push) Waiting to run
repo-contract / repo contract (push) Waiting to run
Shell tests / shell-tests (push) Waiting to run
Shell tests / lib-tests (push) Waiting to run
Shell tests / arch-tests (push) Waiting to run

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Krzysztof Rudnicki 2026-10-04 22:45:34 +02:00
parent c54a1d40c7
commit e288b073b9

View File

@ -1,34 +1,347 @@
[
{"method":"charAt / s[i]","tier":"core","task":"Get the character at index i","call":"s[i] // or s.charAt(i)","mutates":false,"returns":"1-char string; s[i] gives undefined out of range, charAt gives ''","example":"return ['abc'[1],'abc'.charAt(5),'abc'[5]];","expected":"[\"b\",\"\",null]","gotcha":"Strings are immutable: s[0] = 'x' silently does nothing."},
{"method":"charCodeAt","tier":"core","task":"Get the char code of the character at index i","call":"s.charCodeAt(i)","mutates":false,"returns":"number (UTF-16 code unit)","example":"return ['a'.charCodeAt(0),'c'.charCodeAt(0)-'a'.charCodeAt(0)];","expected":"[97,2]","gotcha":"Alphabet index idiom: s.charCodeAt(i) - 97."},
{"method":"String.fromCharCode","tier":"core","task":"Turn a char code into a character","call":"String.fromCharCode(code)","mutates":false,"returns":"string","example":"return String.fromCharCode(97+2);","expected":"\"c\"","gotcha":"Static method on String, not on a string value."},
{"method":"split","tier":"core","task":"Split a string into an array by a separator","call":"s.split(sep)","mutates":false,"returns":"array of strings","signature":"s.split(separator, limit) // split('') = chars","example":"return ['a,b'.split(','),'abc'.split('')];","expected":"[[\"a\",\"b\"],[\"a\",\"b\",\"c\"]]"},
{"method":"[...s]","tier":"core","task":"Turn a string into an array of characters","call":"[...s] // or Array.from(s)","mutates":false,"returns":"new array of characters","example":"return [...'abc'];","expected":"[\"a\",\"b\",\"c\"]","gotcha":"Unlike split(''), spread keeps emoji/surrogate pairs whole."},
{"method":"reverse a string","tier":"core","task":"Reverse a string","call":"[...s].reverse().join('')","mutates":false,"returns":"new string","example":"return [...'abc'].reverse().join('');","expected":"\"cba\"","gotcha":"Strings have no reverse(); go via an array."},
{"method":"slice","tier":"core","task":"Get s[i..j) as a substring","call":"s.slice(i, j)","mutates":false,"returns":"new string; end exclusive","signature":"s.slice(start, end) // end exclusive, negatives count from the end","example":"return ['abcdef'.slice(1,3),'abcdef'.slice(-2)];","expected":"[\"bc\",\"ef\"]"},
{"method":"substring","tier":"core","task":"Substring by two indices (and how it differs from slice)","call":"s.substring(i, j)","mutates":false,"returns":"new string; end exclusive","signature":"s.substring(start, end) // swaps args if start > end, negatives → 0","example":"return ['abcdef'.substring(3,1),'abcdef'.slice(3,1),'abcdef'.substring(-2)];","expected":"[\"bc\",\"\",\"abcdef\"]","gotcha":"Prefer slice(): substring swaps arguments and treats negatives as 0."},
{"method":"indexOf","tier":"core","task":"Find the index of a substring (-1 if absent)","call":"s.indexOf(sub)","mutates":false,"returns":"first index, or -1","signature":"s.indexOf(searchString, fromIndex)","example":"return ['hello'.indexOf('l'),'hello'.indexOf('z')];","expected":"[2,-1]"},
{"method":"includes","tier":"core","task":"Check whether a string contains a substring","call":"s.includes(sub)","mutates":false,"returns":"boolean","example":"return 'hello'.includes('ell');","expected":"true","gotcha":"Case-sensitive; a RegExp argument throws."},
{"method":"startsWith","tier":"core","task":"Check whether a string starts with a prefix","call":"s.startsWith(prefix)","mutates":false,"returns":"boolean","example":"return 'hello'.startsWith('he');","expected":"true"},
{"method":"endsWith","tier":"core","task":"Check whether a string ends with a suffix","call":"s.endsWith(suffix)","mutates":false,"returns":"boolean","example":"return 'hello'.endsWith('lo');","expected":"true"},
{"method":"toLowerCase","tier":"core","task":"Lowercase a string","call":"s.toLowerCase()","mutates":false,"returns":"new string","example":"return 'aBc'.toLowerCase();","expected":"\"abc\""},
{"method":"toUpperCase","tier":"core","task":"Uppercase a string","call":"s.toUpperCase()","mutates":false,"returns":"new string","example":"return 'aBc'.toUpperCase();","expected":"\"ABC\""},
{"method":"trim","tier":"core","task":"Strip whitespace from both ends","call":"s.trim()","mutates":false,"returns":"new string","example":"return ' a b '.trim();","expected":"\"a b\""},
{"method":"repeat","tier":"core","task":"Repeat a string n times","call":"s.repeat(n)","mutates":false,"returns":"new string","example":"return 'ab'.repeat(3);","expected":"\"ababab\"","gotcha":"Negative n throws RangeError."},
{"method":"padStart","tier":"core","task":"Left-pad a string to a length (e.g. zero-pad)","call":"s.padStart(len, '0')","mutates":false,"returns":"new string","signature":"s.padStart(targetLength, padString)","example":"return '5'.padStart(3,'0');","expected":"\"005\""},
{"method":"padEnd","tier":"core","task":"Right-pad a string to a length","call":"s.padEnd(len, ' ')","mutates":false,"returns":"new string","signature":"s.padEnd(targetLength, padString)","example":"return 'ab'.padEnd(5,'.');","expected":"\"ab...\""},
{"method":"replace","tier":"core","task":"Replace occurrences of a pattern (first only vs all)","call":"s.replace(pattern, replacement)","mutates":false,"returns":"new string","signature":"s.replace(patternOrString, replacementOrFn)","example":"return ['aaa'.replace('a','b'),'aaa'.replace(/a/g,'b')];","expected":"[\"baa\",\"bbb\"]","gotcha":"A string pattern replaces only the FIRST match. Use /x/g or replaceAll."},
{"method":"replaceAll","tier":"core","task":"Replace ALL occurrences of a substring","call":"s.replaceAll(sub, replacement)","mutates":false,"returns":"new string","signature":"s.replaceAll(patternOrString, replacementOrFn)","example":"return 'aaa'.replaceAll('a','b');","expected":"\"bbb\"","gotcha":"A RegExp argument must have the g flag or it throws."},
{"method":"at","tier":"core","task":"Get the LAST character (or nth from the end)","call":"s.at(-1)","mutates":false,"returns":"1-char string, or undefined","example":"return ['abc'.at(-1),'abc'.at(0)];","expected":"[\"c\",\"a\"]"},
{"method":"match","tier":"core","task":"Find all regex matches in a string","call":"s.match(/\\d+/g)","mutates":false,"returns":"array of matches, or null if none","example":"return ['a1b22'.match(/\\d+/g),'abc'.match(/\\d+/g)];","expected":"[[\"1\",\"22\"],null]","gotcha":"Without the g flag you get a single match object, not all matches. null → use ?? []."},
{"method":"matchAll","tier":"core","task":"Iterate all regex matches including capture groups","call":"[...s.matchAll(/(\\d)(\\w)/g)]","mutates":false,"returns":"iterator of match arrays","example":"return [...'1a2b'.matchAll(/(\\d)(\\w)/g)].map((m)=>m[1]+m[2]);","expected":"[\"1a\",\"2b\"]","gotcha":"The regex must have the g flag or it throws."},
{"method":"trimStart","tier":"rare","task":"Strip whitespace from the START only","call":"s.trimStart()","mutates":false,"returns":"new string","example":"return ' a '.trimStart();","expected":"\"a \""},
{"method":"trimEnd","tier":"rare","task":"Strip whitespace from the END only","call":"s.trimEnd()","mutates":false,"returns":"new string","example":"return ' a '.trimEnd();","expected":"\" a\""},
{"method":"lastIndexOf","tier":"rare","task":"Find the LAST index of a substring","call":"s.lastIndexOf(sub)","mutates":false,"returns":"last index, or -1","example":"return 'hello'.lastIndexOf('l');","expected":"3"},
{"method":"substr","tier":"rare","task":"Substring by start index and LENGTH (deprecated)","call":"s.substr(start, length)","mutates":false,"returns":"new string","signature":"s.substr(start, length) // deprecated; use slice","example":"return 'abcdef'.substr(1,3);","expected":"\"bcd\"","gotcha":"Second arg is a length, not an end index. Deprecated."},
{"method":"concat","tier":"rare","task":"Concatenate strings with a method call","call":"s.concat(a, b)","mutates":false,"returns":"new string","example":"return 'a'.concat('b','c');","expected":"\"abc\"","gotcha":"Just use + or a template literal."},
{"method":"search","tier":"rare","task":"Find the index of a regex match","call":"s.search(/c/)","mutates":false,"returns":"index, or -1","example":"return 'abc'.search(/c/);","expected":"2"},
{"method":"localeCompare","tier":"rare","task":"Compare two strings for sorting","call":"a.localeCompare(b)","mutates":false,"returns":"negative / 0 / positive number","example":"return ['b','a','c'].sort((x,y)=>x.localeCompare(y));","expected":"[\"a\",\"b\",\"c\"]","gotcha":"Locale-aware and slower; for plain code-unit order use a < b ? -1 : 1."},
{"method":"codePointAt","tier":"rare","task":"Get the full Unicode code point at index i","call":"s.codePointAt(i)","mutates":false,"returns":"number","example":"return '😀'.codePointAt(0);","expected":"128512","gotcha":"charCodeAt would return only half of the surrogate pair."},
{"method":"normalize","tier":"rare","task":"Normalize Unicode (e.g. strip accents with NFD)","call":"s.normalize('NFD')","mutates":false,"returns":"new string","example":"return 'é'.normalize('NFD').length;","expected":"2"}
{
"method": "charAt / s[i]",
"tier": "core",
"task": "Get the character at index i",
"call": "s[i] // or s.charAt(i)",
"mutates": false,
"returns": "1-char string; s[i] gives undefined out of range, charAt gives ''",
"example": "return ['abc'[1],'abc'.charAt(5),'abc'[5]];",
"expected": "[\"b\",\"\",null]",
"gotcha": "Strings are immutable: s[0] = 'x' silently does nothing."
},
{
"method": "charCodeAt",
"tier": "core",
"task": "Get the char code of the character at index i",
"call": "s.charCodeAt(i)",
"mutates": false,
"returns": "number (UTF-16 code unit)",
"example": "return ['a'.charCodeAt(0),'c'.charCodeAt(0)-'a'.charCodeAt(0)];",
"expected": "[97,2]",
"gotcha": "Alphabet index idiom: s.charCodeAt(i) - 97."
},
{
"method": "String.fromCharCode",
"tier": "core",
"task": "Turn a char code into a character",
"call": "String.fromCharCode(code)",
"mutates": false,
"returns": "string",
"example": "return String.fromCharCode(97+2);",
"expected": "\"c\"",
"gotcha": "Static method on String, not on a string value."
},
{
"method": "split",
"tier": "core",
"task": "Split a string into an array by a separator",
"call": "s.split(sep)",
"mutates": false,
"returns": "array of strings",
"signature": "s.split(separator, limit) // split('') = chars",
"example": "return ['a,b'.split(','),'abc'.split('')];",
"expected": "[[\"a\",\"b\"],[\"a\",\"b\",\"c\"]]"
},
{
"method": "[...s]",
"tier": "core",
"task": "Turn a string into an array of characters",
"call": "[...s] // or Array.from(s)",
"mutates": false,
"returns": "new array of characters",
"example": "return [...'abc'];",
"expected": "[\"a\",\"b\",\"c\"]",
"gotcha": "Unlike split(''), spread keeps emoji/surrogate pairs whole."
},
{
"method": "reverse a string",
"tier": "core",
"task": "Reverse a string",
"call": "[...s].reverse().join('')",
"mutates": false,
"returns": "new string",
"example": "return [...'abc'].reverse().join('');",
"expected": "\"cba\"",
"gotcha": "Strings have no reverse(); go via an array."
},
{
"method": "slice",
"tier": "core",
"task": "Get s[i..j) as a substring",
"call": "s.slice(i, j)",
"mutates": false,
"returns": "new string; end exclusive",
"signature": "s.slice(start, end) // end exclusive, negatives count from the end",
"example": "return ['abcdef'.slice(1,3),'abcdef'.slice(-2)];",
"expected": "[\"bc\",\"ef\"]"
},
{
"method": "substring",
"tier": "core",
"task": "Substring by two indices (and how it differs from slice)",
"call": "s.substring(i, j)",
"mutates": false,
"returns": "new string; end exclusive",
"signature": "s.substring(start, end) // swaps args if start > end, negatives → 0",
"example": "return ['abcdef'.substring(3,1),'abcdef'.slice(3,1),'abcdef'.substring(-2)];",
"expected": "[\"bc\",\"\",\"abcdef\"]",
"gotcha": "Prefer slice(): substring swaps arguments and treats negatives as 0."
},
{
"method": "indexOf",
"tier": "core",
"task": "Find the index of a substring (-1 if absent)",
"call": "s.indexOf(sub)",
"mutates": false,
"returns": "first index, or -1",
"signature": "s.indexOf(searchString, fromIndex)",
"example": "return ['hello'.indexOf('l'),'hello'.indexOf('z')];",
"expected": "[2,-1]"
},
{
"method": "includes",
"tier": "core",
"task": "Check whether a string contains a substring",
"call": "s.includes(sub)",
"mutates": false,
"returns": "boolean",
"example": "return 'hello'.includes('ell');",
"expected": "true",
"gotcha": "Case-sensitive; a RegExp argument throws."
},
{
"method": "startsWith",
"tier": "core",
"task": "Check whether a string starts with a prefix",
"call": "s.startsWith(prefix)",
"mutates": false,
"returns": "boolean",
"example": "return 'hello'.startsWith('he');",
"expected": "true"
},
{
"method": "endsWith",
"tier": "core",
"task": "Check whether a string ends with a suffix",
"call": "s.endsWith(suffix)",
"mutates": false,
"returns": "boolean",
"example": "return 'hello'.endsWith('lo');",
"expected": "true"
},
{
"method": "toLowerCase",
"tier": "core",
"task": "Lowercase a string",
"call": "s.toLowerCase()",
"mutates": false,
"returns": "new string",
"example": "return 'aBc'.toLowerCase();",
"expected": "\"abc\""
},
{
"method": "toUpperCase",
"tier": "core",
"task": "Uppercase a string",
"call": "s.toUpperCase()",
"mutates": false,
"returns": "new string",
"example": "return 'aBc'.toUpperCase();",
"expected": "\"ABC\""
},
{
"method": "trim",
"tier": "core",
"task": "Strip whitespace from both ends",
"call": "s.trim()",
"mutates": false,
"returns": "new string",
"example": "return ' a b '.trim();",
"expected": "\"a b\""
},
{
"method": "repeat",
"tier": "core",
"task": "Repeat a string n times",
"call": "s.repeat(n)",
"mutates": false,
"returns": "new string",
"example": "return 'ab'.repeat(3);",
"expected": "\"ababab\"",
"gotcha": "Negative n throws RangeError."
},
{
"method": "padStart",
"tier": "core",
"task": "Left-pad a string to a length (e.g. zero-pad)",
"call": "s.padStart(len, '0')",
"mutates": false,
"returns": "new string",
"signature": "s.padStart(targetLength, padString)",
"example": "return '5'.padStart(3,'0');",
"expected": "\"005\""
},
{
"method": "padEnd",
"tier": "core",
"task": "Right-pad a string to a length",
"call": "s.padEnd(len, ' ')",
"mutates": false,
"returns": "new string",
"signature": "s.padEnd(targetLength, padString)",
"example": "return 'ab'.padEnd(5,'.');",
"expected": "\"ab...\""
},
{
"method": "replace",
"tier": "core",
"task": "Replace occurrences of a pattern (first only vs all)",
"call": "s.replace(pattern, replacement)",
"mutates": false,
"returns": "new string",
"signature": "s.replace(patternOrString, replacementOrFn)",
"example": "return ['aaa'.replace('a','b'),'aaa'.replace(/a/g,'b')];",
"expected": "[\"baa\",\"bbb\"]",
"gotcha": "A string pattern replaces only the FIRST match. Use /x/g or replaceAll."
},
{
"method": "replaceAll",
"tier": "core",
"task": "Replace ALL occurrences of a substring",
"call": "s.replaceAll(sub, replacement)",
"mutates": false,
"returns": "new string",
"signature": "s.replaceAll(patternOrString, replacementOrFn)",
"example": "return 'aaa'.replaceAll('a','b');",
"expected": "\"bbb\"",
"gotcha": "A RegExp argument must have the g flag or it throws."
},
{
"method": "at",
"tier": "core",
"task": "Get the LAST character (or nth from the end)",
"call": "s.at(-1)",
"mutates": false,
"returns": "1-char string, or undefined",
"example": "return ['abc'.at(-1),'abc'.at(0)];",
"expected": "[\"c\",\"a\"]"
},
{
"method": "match",
"tier": "core",
"task": "Find all regex matches in a string",
"call": "s.match(/\\d+/g)",
"mutates": false,
"returns": "array of matches, or null if none",
"example": "return ['a1b22'.match(/\\d+/g),'abc'.match(/\\d+/g)];",
"expected": "[[\"1\",\"22\"],null]",
"gotcha": "Without the g flag you get a single match object, not all matches. null → use ?? []."
},
{
"method": "matchAll",
"tier": "core",
"task": "Iterate all regex matches including capture groups",
"call": "[...s.matchAll(/(\\d)(\\w)/g)]",
"mutates": false,
"returns": "iterator of match arrays",
"example": "return [...'1a2b'.matchAll(/(\\d)(\\w)/g)].map((m)=>m[1]+m[2]);",
"expected": "[\"1a\",\"2b\"]",
"gotcha": "The regex must have the g flag or it throws."
},
{
"method": "trimStart",
"tier": "rare",
"task": "Strip whitespace from the START only",
"call": "s.trimStart()",
"mutates": false,
"returns": "new string",
"example": "return ' a '.trimStart();",
"expected": "\"a \""
},
{
"method": "trimEnd",
"tier": "rare",
"task": "Strip whitespace from the END only",
"call": "s.trimEnd()",
"mutates": false,
"returns": "new string",
"example": "return ' a '.trimEnd();",
"expected": "\" a\""
},
{
"method": "lastIndexOf",
"tier": "rare",
"task": "Find the LAST index of a substring",
"call": "s.lastIndexOf(sub)",
"mutates": false,
"returns": "last index, or -1",
"example": "return 'hello'.lastIndexOf('l');",
"expected": "3"
},
{
"method": "substr",
"tier": "rare",
"task": "Substring by start index and LENGTH (deprecated)",
"call": "s.substr(start, length)",
"mutates": false,
"returns": "new string",
"signature": "s.substr(start, length) // deprecated; use slice",
"example": "return 'abcdef'.substr(1,3);",
"expected": "\"bcd\"",
"gotcha": "Second arg is a length, not an end index. Deprecated."
},
{
"method": "concat",
"tier": "rare",
"task": "Concatenate strings with a method call",
"call": "s.concat(a, b)",
"mutates": false,
"returns": "new string",
"example": "return 'a'.concat('b','c');",
"expected": "\"abc\"",
"gotcha": "Just use + or a template literal."
},
{
"method": "search",
"tier": "rare",
"task": "Find the index of a regex match",
"call": "s.search(/c/)",
"mutates": false,
"returns": "index, or -1",
"example": "return 'abc'.search(/c/);",
"expected": "2"
},
{
"method": "localeCompare",
"tier": "rare",
"task": "Compare two strings for sorting",
"call": "a.localeCompare(b)",
"mutates": false,
"returns": "negative / 0 / positive number",
"example": "return ['b','a','c'].sort((x,y)=>x.localeCompare(y));",
"expected": "[\"a\",\"b\",\"c\"]",
"gotcha": "Locale-aware and slower; for plain code-unit order use a < b ? -1 : 1."
},
{
"method": "codePointAt",
"tier": "rare",
"task": "Get the full Unicode code point at index i",
"call": "s.codePointAt(i)",
"mutates": false,
"returns": "number",
"example": "return '😀'.codePointAt(0);",
"expected": "128512",
"gotcha": "charCodeAt would return only half of the surrogate pair."
},
{
"method": "normalize",
"tier": "rare",
"task": "Normalize Unicode (e.g. strip accents with NFD)",
"call": "s.normalize('NFD')",
"mutates": false,
"returns": "new string",
"example": "return 'é'.normalize('NFD').length;",
"expected": "2"
}
]