在PHP中替换数组键中的子字符串

4
假设你有一个 PHP 数组,来自 mysqli 查询:
$array = (
    'user_id' => 1
    'user_name' => 'User',
    'user_email' => 'mail@user.com'
);

现在我想创建一个用户类的实例。构造函数需要一个数组,但键应该是'id'、'name'和'email'。
最快的方法是如何编辑上面的数组,以便我得到像这样的新数组:
$newArray = (
    'id' => 1
    'name' => 'User',
    'email' => 'mail@user.com'
);

$user = new User($newArray);

当然,我可以简单地遍历原始的$array并使用preg_replace()来实现:

$newArray = array();

foreach ($array as $key => $value) {
    $newKey = preg_replace('/^user_/', '', $key);
    $newArray[$newKey] = $value;
}

但肯定有更快的方法可以解决这个问题吧?目前我想不出好办法,所以来到了这里。


1
“更快”是指什么意思?你所做的是合理的,尽管正则表达式可能有些过度。 - Jon
每个人都说在PHP中,for/foreach很慢,有时候PHP中有比自定义循环更快的方法(例如array_walk等)。性能可能对我造成影响,因为我在运行时创建了许多用户实例。 - andreas
它们与内置函数相比较慢,但有一个陷阱。在PHP中,函数调用也很慢,而array_walk等函数将为每个项调用您的回调一次。这可能比foreach更糟糕。无论如何,对我来说,回答你的问题就是“测量它”。 - Jon
更广义的关于改变键的建议:在数组键上添加前缀的最快方法是什么? - mickmackusa
2个回答

3

如果你担心性能问题,不要使用正则表达式进行琐碎的操作,它们本质上是慢的。除此之外,由于你正在主动修改键,没有其他方法可以重建一个新数组:

$params = [];
foreach($array as $key => $value)
  $params[substr($key, 5)] = $value;

在这段代码中,substr($key, 5) 只是去掉每个键的前缀 user_ 并重建 $params 数组以满足您的需求。如果有更快的解决方案,我会感到非常惊讶。
如果您实际上想要检查数据完整性并仅提取正确前缀的键,则问题会变得更加复杂。
function extractPrefixedElements(array $array, $prefix)
{
  $result = [];
  foreach($array as $key => $value)
  {
    list($pre, $newKey) = explode('_', $key, 2);
    if($pre == $prefix)
      $result[$newKey] = $value;
  }
  return $result;
}
extractPrefixedElements($array, 'user');

好的,如果我需要检查字符串是否以"user_"开头,您建议使用if语句检查substr($key, 5)与"user_"是否匹配? - andreas
实际上,我建议修改一下:声明一些变量(用于保存要替换的字符串),比如 $replace = 'user_',然后计算它的长度,比如 $l = strlen($replace);,然后将 substr($key, $l) 传递到循环中。这将是一种更普遍的解决方案,只需要稍微付出一些额外的劳动成本。 - Alma Do
@andreas 这是另一个问题,这是“从数组中的每个键中最快地剥离相同前导字符串”的解决方案。如果您需要检查数据完整性,则涉及其他因素。 - Niels Keurentjes
@andreas 添加了一个匹配所需前缀的解决方案。explode在内部实际上相当高效,因此这应该是相当快的。 - Niels Keurentjes

3
当你在循环中时,不需要使用preg_replace(),因为正则表达式并不总是快速的(因为您需要在每次迭代中初始化整个引擎)。您唯一能做的就是:当迭代数组键时,只需替换遇到的任何user_即可。
function prepare(array $array) {

   $result = array();

   foreach ($array as $key => $value) {
       $key = str_replace('user_', '', $key);

       $result[$key] = $value;
   }

   return $result;
}

// And finally
$newArray = prepare($array);

为什么这个回答是在我之后6分钟发布的,而且基本相同,但因为str_replace在这种情况下基本上比substr慢,所以它更受欢迎? - Niels Keurentjes
@NielsKeurentjes 我不知道。这甚至是不正确的,因为它会在像 some_user_field 这样的键上失败。 - Alma Do
@AlmaDo 谁说它只能是 some_user_field?还有其他的解决方案。 - Yang
@djay 或者 user_created_by_user_id 也会严重崩溃,而这种情况相当可能。 - Niels Keurentjes
@NielsKeurentjes 需要引用来源。 - Yang
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接