array_filter 有元素修改
array_filter with element modification
我正在尝试从我的用户将定义的字符串创建一个干净的数组。
该字符串可以包含无效的 ID、空格等。我在 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;
}
}
)
);
这很好用,但我要应用 trim
两次。有没有更好的方法或不同的 PHP 函数,我可以在其中修改元素,然后再将其保存在返回的数组中?
注意:我也可以在 array_filter
的第一个参数中调用 array_map
,但无论如何我都会遍历数组两次。
就看你是否在乎性能了。如果这样做,请不要使用 map+filter,而是使用普通的 for 循环并就地操作数组:
$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
当然,如果这是无关紧要的代码,那么修剪两次确实不会造成性能差异,但您仍然可以清理它们:
$arr = explode(',', $input);
$arr = array_filter(
array_map('Id.isValidId', $arr),
function ($i) {
return $i !== false;
}
);
在这个例子中,我们首先使用那个函数进行映射,所以我们得到一个id数组和false
值,然后我们过滤它,这样所有false
被扔掉,而不是先过滤,再映射。
(在这两种情况下,负责检查有效性的代码都在 Id
class 中,它要么是 returns 一个清理过的 id,要么是 false
)
其实你可以用不同的方式来做,但如果我是你,我会这样做。这里我只用了一个trim
<?php
$definedIds = "123,1234,1243, 12434 , asdf"; //from users panel
function my_filter($b){
if(is_numeric($b)){
return true;
}
}
print '<pre>';
$trimmed = array_map('trim',explode(',',$definedIds));
print_r(array_filter($trimmed,my_filter));
print '</pre>';
?>
程序输出:
Array
(
[0] => 123
[1] => 1234
[2] => 1243
[3] => 12434
)
我正在尝试从我的用户将定义的字符串创建一个干净的数组。
该字符串可以包含无效的 ID、空格等。我在 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;
}
}
)
);
这很好用,但我要应用 trim
两次。有没有更好的方法或不同的 PHP 函数,我可以在其中修改元素,然后再将其保存在返回的数组中?
注意:我也可以在 array_filter
的第一个参数中调用 array_map
,但无论如何我都会遍历数组两次。
就看你是否在乎性能了。如果这样做,请不要使用 map+filter,而是使用普通的 for 循环并就地操作数组:
$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
当然,如果这是无关紧要的代码,那么修剪两次确实不会造成性能差异,但您仍然可以清理它们:
$arr = explode(',', $input);
$arr = array_filter(
array_map('Id.isValidId', $arr),
function ($i) {
return $i !== false;
}
);
在这个例子中,我们首先使用那个函数进行映射,所以我们得到一个id数组和false
值,然后我们过滤它,这样所有false
被扔掉,而不是先过滤,再映射。
(在这两种情况下,负责检查有效性的代码都在 Id
class 中,它要么是 returns 一个清理过的 id,要么是 false
)
其实你可以用不同的方式来做,但如果我是你,我会这样做。这里我只用了一个trim
<?php
$definedIds = "123,1234,1243, 12434 , asdf"; //from users panel
function my_filter($b){
if(is_numeric($b)){
return true;
}
}
print '<pre>';
$trimmed = array_map('trim',explode(',',$definedIds));
print_r(array_filter($trimmed,my_filter));
print '</pre>';
?>
程序输出:
Array
(
[0] => 123
[1] => 1234
[2] => 1243
[3] => 12434
)