【问题标题】:Remove array key prefix recursively递归删除数组键前缀
【发布时间】:2023-03-22 07:25:02
【问题描述】:

我有一个格式如下的数组(每个子数组都有父键作为前缀):

$input = array(
    'seo_text' => array(
        'seo_text_title'       => '',
        'seo_text_description' => '',
        'seo_text_button'      => array(
            'seo_text_button_text' => '',
            'seo_text_button_url'  => '',
            'seo_text_button_new_tab_enabled' => '',
        ),
    ),
);

我想把它转换成以下格式:

$input = array(
    'seo_text' => array(
        'title'       => '',
        'description' => '',
        'button'      => array(
            'text' => '',
            'url'  => '',
            'new_tab_enabled' => '',
        ),
    ),
);

我正在尝试编写一个递归函数,但它并没有按照预期的方式工作。

【问题讨论】:

  • 至少告诉我们你尝试了什么。请阅读How to Ask
  • 你尝试了什么?
  • 你的问题是有道理的,但是这个平台不是免费的源代码提供者。你试过什么?显示一些代码
  • 我们至少可以给出一些必要的主题来让你的逻辑。看到这些,Keystr_replace

标签: php arrays recursion


【解决方案1】:

解决方案:

function removeKeyPrefix(array $array, string $prefix = ''): array
{
    $newArray = [];
    $prefixLength = strlen($prefix);

    foreach ($array as $key => $value) {
        if (substr($key, 0, $prefixLength) === $prefix) {
            $newKey = substr($key, $prefixLength);
        } else {
            $newKey = $key;
        }

        $newArray[$newKey] = is_array($value) ? removeKeyPrefix($value, $key.'_') : $value;
    }

    return $newArray;
}

$input = removeKeyPrefix($input);

Online demo on 3v4l

【讨论】:

  • @MarcosPérezGude:确实如此,但唯一的问题是它不起作用。
  • @CasimiretHippolyte OMG!它有很好的味道,但我不测试它是否知道它是否有效。但是,看起来打字不错,代码也有意义,我不会删除赞成票,因为它可能不适用于这种情况,但其他用户可以看到此代码并改进他的代码。
  • @MarcosPérezGude:缺少一些(但很重要)的东西:给前缀一个默认的空值,在循环中使用当前键调用函数,测试键是否为空,最终是一个整数在定义前缀之前。
  • @CasimiretHippolyte 修复了代码。请检查一下。
【解决方案2】:
function sanitizeKeys(array $items, $previousKey = '') : array
{
    $previousKey .= "_";

    return array_reduce(
        array_keys($items),
        function($result, $key) use ($previousKey, $items) {
            $newKey = (0 === strpos($key, $previousKey)) ? substr_replace($key, '', 0, strlen($previousKey)) : $key;

            $result[$newKey] = is_array($items[$key]) ? sanitizeKeys($items[$key], $key) : $items[$key];

            return $result;
        }, []
    );
};

sanitizeKeys($input);

【讨论】:

  • 其实唯一正确的答案(唯一读过要求的人)。
【解决方案3】:

创建一个函数来更改 slug 中的最后一次出现

function fun($array,$slug){
  foreach($array as $key=>$val){
    $last = end(explode($slug,$key));

    if(is_array($val)){
      $val = fun($val,$key."_");  
    }
    $array[$last] = $val;
    unset($array[$key]);
  }
  return $array;
}
$input["seo_text"] = fun($input["seo_text"],"seo_text_");
print_r($input);

现场演示:https://eval.in/934155

输出是

Array
(
    [seo_text] => Array
        (
            [title] => 
            [description] => 
            [button] => Array
                (
                    [text] => 
                    [url] => 
                    [new_tab_enabled] => 
                )

        )

)

如果您在第二级有很多元素,请使用foreach 调用如下函数

foreach($input as $key=>$val){
  $input[$key] = fun($val,$key."_");
}
print_r($input);

https://eval.in/934156

【讨论】:

  • 有趣,但最后一个键必须是new_tab_enabled 而不是enabled
  • @CasimiretHippolyte:你说得对,我已经更新了我的答案。
  • 第一个键必须是seo_text 而不是text。对不起。
  • @CasimiretHippolyte:函数没有变化,只是我们可以用另一种方式调用。我刚刚打电话给$input["seo_text"] = fun($input["seo_text"],"seo_text_"); print_r($input);
猜你喜欢
  • 2012-01-26
  • 2017-08-15
  • 2020-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-28
  • 2014-01-08
  • 2016-11-25
相关资源
最近更新 更多