array_filter,带元素修改

时间:2018-05-01 13:45:56

标签: php array-filter

我正在尝试从用户将定义的字符串中创建一个干净的数组。 该字符串可以包含无效的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_map的第一个参数中调用array_filter,但无论如何我都会循环遍历数组。

2 个答案:

答案 0 :(得分:1)

这取决于你是否关心表现。如果这样做,请不要使用map + filter,而是使用plain 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类中,并且它返回一个已清除的ID或false

答案 1 :(得分:0)

实际上你可以用不同的方式做到,但如果我是你,那么我会这样做。在这里,我只使用了一个 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
)

DEMO: https://eval.in/997812