Need help/clarification with caching results from the PHP method that takes a string and returns the number of unique characters in the string (method below ⬇️ done and works)
function uniqueCharacters($str): int
{
$counter = [];
$splitted = str_split($str);
foreach($splitted as $s) {
if(!isset($counter[$s]))
$counter[$s] = 0;
$counter[$s] ;
}
$unique = array_keys(array_filter($counter, function($c) {
return $c == 1;
}));
return count($unique);
}
It is expected that a string with the same character sequence may be passed several times to the method. Since the counting operation can be time-consuming, the method should cache the results, so that when the method is given a string previously encountered, it will simply retrieve the stored result. Use collections and maps where appropriate.
Tried a solution from https://stackoverflow.com/questions/3540403/caching-function-results-in-php but that one is not what was asked from the task...
CodePudding user response:
Just keep a static cache in your function and only do the work if encountering the string for the first time.
Because you only have a single string as an incoming parameter, you don't need to serialize the data to form a string. When declaring string keys in an array, those values will not be corrupted. However if your values are floats, booleans, null, arrays, objects, resources, (and probably a few other types that I'm not thinking of) then you'd better convert it to some form of string to be safe. In other words, you can safely use my snippet if your incoming parameter is string or int typed (not a mix of int and strings).
Code: (Demo)
function countUniqueCharacters(string $str): int
{
static $cache = [];
if (key_exists($str, $cache)) {
return $cache[$str];
}
echo PHP_EOL . "*** doing the work ***";
return $cache[$str] = count(
array_filter(
count_chars($str, 1),
fn($count) => $count === 1
)
);
}
$tests = ['one', 'two', 'three', 'one', 'two'];
foreach ($tests as $test) {
echo PHP_EOL . "$test : " . countUniqueCharacters($test);
}
Because your return value is an int (cannot be null), you can simplify the above as: (Demo)
function countUniqueCharacters(string $str): int
{
static $cache = [];
return $cache[$str] ??= count(
array_filter(
count_chars($str, 1),
fn($count) => $count === 1
)
);
}
Relevant links: