将数组/对象树的键转换为小写

2023-12-02

我目前正在优化一个 PHP 应用程序,发现一个函数被调用了大约 10-20k 次,所以我想我应该从那里开始优化:

function keysToLower($obj)
{
        if(!is_object($obj) && !is_array($obj)) return $obj;
        foreach($obj as $key=>$element)
        {
                $element=keysToLower($element);
                if(is_object($obj))
                {
                        $obj->{strtolower($key)}=$element;
                        if(!ctype_lower($key)) unset($obj->{$key});
                }
                else if(is_array($obj) && ctype_upper($key))
                {
                        $obj[strtolower($key)]=$element;
                        unset($obj[$key]);
                }
        }
        return $obj;
}

大部分时间都花在递归调用上(这在 PHP 中相当慢),但我没有看到任何方法将其转换为循环。 你会怎么办?

这个版本不考虑关联数组,因为我的数据没有关联数组,但比原始版本快了近 10 倍。大部分工作是由 Gumbo 完成的,主要的加速来自于使用引用和创建一个新对象,而不是取消设置旧的键。

function &keysToLower(&$obj)
{
    if(is_object($obj))
    {
        $newobj = (object) array();
        foreach ($obj as $key => &$val)
            $newobj->{strtolower($key)} = keysToLower($val);
        $obj=$newobj;
    }
    else if(is_array($obj))
        foreach($obj as &$value)
            keysToLower($value);
    return $obj;
}

Foreach正在使用随后被遍历的内部副本。尝试不使用:

function keysToLower($obj)
{
    $type = (int) is_object($obj) - (int) is_array($obj);
    if ($type === 0) return $obj;
    reset($obj);
    while (($key = key($obj)) !== null)
    {
        $element = keysToLower(current($obj));
        switch ($type)
        {
        case 1:
            if (!is_int($key) && $key !== ($keyLowercase = strtolower($key)))
            {
                unset($obj->{$key});
                $key = $keyLowercase;
            }
            $obj->{$key} = $element;
            break;
        case -1:
            if (!is_int($key) && $key !== ($keyLowercase = strtolower($key)))
            {
                unset($obj[$key]);
                $key = $keyLowercase;
            }
            $obj[$key] = $element;
            break;
        }
        next($obj);
    }
    return $obj;
}

或者使用引用来避免使用副本:

function &keysToLower(&$obj)
{
    $type = (int) is_object($obj) - (int) is_array($obj);
    if ($type === 0) return $obj;
    foreach ($obj as $key => &$val)
    {
        $element = keysToLower($val);
        switch ($type)
        {
        case 1:
            if (!is_int($key) && $key !== ($keyLowercase = strtolower($key)))
            {
                unset($obj->{$key});
                $key = $keyLowercase;
            }
            $obj->{$key} = $element;
            break;
        case -1:
            if (!is_int($key) && $key !== ($keyLowercase = strtolower($key)))
            {
                unset($obj[$key]);
                $key = $keyLowercase;
            }
            $obj[$key] = $element;
            break;
        }
    }
    return $obj;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将数组/对象树的键转换为小写 的相关文章

随机推荐

  • 椭圆的标准形式

    我得到椭圆作为拟合数据集的水平曲线 选择特定椭圆后 我想将其报告为中心点 半长轴和短轴长度以及旋转角度 换句话说 我想将我的椭圆方程转换为 使用mathematica Ax 2 By 2 Cx Dy Exy F 0 更标准的形式 xCos
  • IdentityServer4 AddSignerCredentials RSA 示例

    准备将 IdentityServer4 设置从开发版移至测试版 我需要从 AddDeveloperCredentials 迁移 AddSignerCredentials 部分 我可以生成私有和公共 RSASecurityKey 但我不清楚将
  • 非法参数:未定义、字符串

    注册用户时出现此错误 节点 13225 UnhandledPromiseRejectionWarning 错误 非法 参数 未定义 字符串 在 Object bcrypt hashSync home admin Desktop projec
  • Scala 编译 OptionBuilder 时出错

    我正在使用 Apache commons cli 1 2 进行命令行解析 我的代码中有以下内容 import org apache commons cli OptionBuilder OptionBuilder withLongOpt db
  • 为什么 ghci 找不到我尝试编译的 hs 文件?

    我是第一次学习 Haskell 我不明白为什么 ghci 找不到我正在尝试编译的文件 特别是因为我保存了文件 这是我的文件 import System IO trueAndFalse True False 现在这就是我在编译器中运行的内容
  • 防止双击按钮

    我一直遇到用户双击网络应用程序上的操作按钮的问题 这意味着重复的记录被添加到我的数据库中 有时用户会被收取两次费用 因为该操作运行了两次 在 ASP NET 中防止双击的最佳方法是什么 我发现您在面对未启用 JavaScript 的用户时对
  • 如何在 Pyqt5 setcentralWidget 中取回我的主窗口? [复制]

    这个问题在这里已经有答案了 如何取回我的主窗口 从我的主窗口 如果我按 打开左边的盒子 按钮或 打开右边的盒子 按钮 它起作用了 同时 如果我按下 Back 从左框按钮 什么也不会发生 如何获取主窗口 简单来说 我想知道如何设置布局和删除布
  • Room 为离线应用程序创建备份的最佳方法?

    所以我可以说正在使用非常复杂的数据库many to many数据库设计与foreign keys并连接表 它是Room数据库 我想为其创建备份系统 因为它是离线应用程序 我需要导出数据库并将其存储到谷歌驱动器的应用程序文件夹中 最近几天我读
  • 搜索按钮上的进度条

    我有这个 C 代码来显示进度条 public partial class FormPesquisaFotos Form public FormPesquisaFotos InitializeComponent private void Fo
  • switch 语句的逻辑部分或 case 部分如何?

    如果您有一个 switch 语句并希望在值为一个值时运行某些代码or另一个你怎么做 以下代码始终进入默认情况 include
  • Java Paths.get .... readAllBytes(path)) 不适用于相对路径

    我是 Java 新手 正在尝试构建 FX 应用程序 我的功能之一旨在用其他字符串替换某些字符串 只要我定义目标文件的绝对路径 该脚本就可以正常工作 但当我使用相对路径时 该脚本就会中断 问题出在 readAllBytes 方法中 该方法仅适
  • JPA - 可以在不提供可选参数的情况下调用存储过程吗?

    我正在调用带有许多可选参数的第三方存储过程 它位于 MS SQL Server 2008 R2 中 如下所示 procedure dbo pTest ReportDate varbinary max out Optional1 varcha
  • “?”附近的语法不正确: Nhibernate 生成的查询

    我在 Nhbernate 中使用位置参数时遇到问题 Criteria GroupProperty 正在发出带有命名变量和位置变量的 SQL 这个说法 session CreateCriteria typeof MatchStageFrom
  • 如何将 Matlab 函数的输出分配给单行中的变量?

    matlab中有没有一种方法可以将matlab中函数的输出分配给单行内的向量 例如 此函数应分配周长和面积值 function p a square geom side p perimeter square side a side 2 p
  • 分两列打印

    我们应该形成一个出现 108 次的名称数组 我们应该在左列中包含名称 1 54 在右列中包含名称 55 108 当一页有 108 个名称后 我们初始化数组并重新开始 我的代码的输出显示打印的名称 1 54 并且名称 55 108 不是位于同
  • Angular 2-ngModel 中的更改未反映在下拉列表中

    所以我有一个非常简单的场景 其中在下拉列表更改时显示确认弹出窗口 如果用户选择取消 我需要将下拉值恢复为旧值 我认为我做得正确 甚至在 DOM 中 ngModel 的值与select正在反映 但不知何故 它并没有恢复显示中的选定值 这是我的
  • 以编程方式获取框架 ID

    有人知道是否有办法以编程方式获取当前框架 ID 是的 您可以在 Play 类上获取该属性 Play id
  • 离散小波变换 Matlab

    我正在尝试使用 Matlab 小波工具箱中提供的函数来创建图像的多级离散小波分解 提取系数 操作它们 并将它们重新组合回图像中 我尝试使用许多函数 但它们似乎都不能满足我的需要 以下是执行此操作的步骤 使用wavedec2将图像分解为 C
  • 在 C# 中,这段带有“get”的代码是什么意思?

    我是 C 新手 private string m public string M get return m C 中的这种 getter setter 是否像 Java 一样 这部分是一个字段 private string m 这部分是一个只
  • 将数组/对象树的键转换为小写

    我目前正在优化一个 PHP 应用程序 发现一个函数被调用了大约 10 20k 次 所以我想我应该从那里开始优化 function keysToLower obj if is object obj is array obj return ob