I'm trying to make a clean array from a string that my users will define.
The string can contain non-valid IDs, spaces, etc. I'm checking the elements using a value object in a callback function for array_filter
.
$definedIds = "123,1234,1243, 12434 , asdf"; //from users panel
$validIds = array_map(
'trim',
array_filter(
explode(",", $definedIds),
function ($i) {
try {
new Id(trim($i));
return true;
} catch (\Exception $e) {
return false;
}
}
)
);
This works fine, but I'm applying trim
twice. Is there a better way to do this or a different PHP function in which I can modify the element before keeping it in the returned array?
NOTE: I also could call array_map
in the first parameter of array_filter
, but I would be looping through the array twice anyway.
It depends on whether you care about performance. If you do, don't use map+filter, but use a plain for loop and manipulate your array in place:
$arr = explode(',', $input);
for($i=count($arr)-1; $i>=0; $i--) {
// make this return trimmed string, or false,
// and have it trim the input instead of doing
// that upfront before passing it into the function.
$v = $arr[$i] = Id.makeValid($arr[$i]);
// weed out invalid ids
if ($v === false) {
array_splice($arr, $i, 1);
}
}
// at this point, $arr only contains valid, cleaned ids
Of course, if this is inconsequential code, then trimming twice is really not going to make a performance difference, but you can still clean things up:
$arr = explode(',', $input);
$arr = array_filter(
array_map('Id.isValidId', $arr),
function ($i) {
return $i !== false;
}
);
In this example we first map using that function, so we get an array of ids and false
values, and then we filter that so that everything that's false
gets thrown away, rather than first filtering, and then mapping.
(In both cases the code that's responsible for checking validity is in the Id
class, and it either returns a cleaned id, or false
)