【问题标题】:Removing JSON children by key in PHP在 PHP 中按键删除 JSON 子节点
【发布时间】:2019-05-23 07:27:50
【问题描述】:

我的目标是有一个函数可以删除指定的 json 子级,它也可以嵌套在更深的内部。

我的函数如下所示:

private function removeJsonChild(String $jsonKey, String $jsonString)
{
    $json = json_decode($jsonString, true);
    $arr_index = array();

    foreach ($json as $key => $value) {
        if (is_array($value)) {
            $json[$key] = $this->removeJsonChild($jsonKey, json_encode($value));
        }

        if ($key == $jsonKey) {
            $arr_index[] = $key;
        }
    }

    foreach ($arr_index as $i) {
        unset($json[$i]);
    }

    return json_encode($json);
}

如果我不检查 $value 是否是一个数组,然后再次递归调用该函数,该函数将起作用。但是我认为有问题。在我将函数的返回值分配给$json[$key] 的语句中。我做错了什么?

编辑:肯定忘记了json_decode。新代码如下所示:

private function removeJsonChild(String $jsonKey, String $jsonString)
{
    $json = json_decode($jsonString, true);
    $arr_index = array();

    foreach ($json as $key => $value) {
        if (is_array($value)) {
            $json[$key] = json_decode($this->removeJsonChild($jsonKey, json_encode($value)));
        }

        if ($key == $jsonKey) {
            $arr_index[] = $key;
        }
    }

    foreach ($arr_index as $i) {
        unset($json[$i]);
    }

    return json_encode($json);
}

EDIT2

该函数现在可以工作,但是它稍微改变了 json 架构。

这样的 JSON:

[
  {
    "id": 1,
    "name": "oyzadsaigny647"
  }
]

现在变成这样:

{
  "1": {
    "id": 1,
    "name": "oyzadsaigny647"
  }
}

【问题讨论】:

  • 首先,这里的职责分离。编写一个可以从数组中删除键的递归函数。然后编写第二个函数,它关心 JSON 的编码/解码。
  • 它可以与 json_decode 一起使用吗?
  • 查看我上次的编辑
  • 这看起来像是一个学习 TDD 的完美示例项目 - 尝试编写测试用例,从最简单的用例开始,以满足该要求。如果沿途没有成功,请分享您的尝试

标签: php json


【解决方案1】:
private function removeJsonChild(String $jsonKey, String $jsonString) {

   $data = json_decode($jsonString, true);

   $data = $this->removeKeyFromArray($key, $data);

   return json_encode($data);

}

private function removeKeyFromArray(String $deleteKey, array $data) {

  unset($data[$deleteKey]); // No need to check if it exists, it just does nothing in that case

  foreach($data as $key => value) {
    if(is_array($value)) {
        $data[$key] = $this->removeKeyFromArray($deleteKey, $value);
    }
  }
  return $data;
}

注意:这适用于字典,即具有实际 keys 的数组。如果您有一个普通数组,例如[1, 10, 23, 15],则未设置的行为是错误的,正如@deceze♦ 所指出的那样

【讨论】:

  • 感谢您的回答。对于这样的 json 对象非常有效:{ "id": 1, "name": "oyziasasgny647", "status": "active", "lastUpdate": "2019-03-08T00:00:00+00:00" } 但不适用于此:[ { "id": 1, "name": "oyziasasgny647", "status": "active", "lastUpdate": "2019-03-08T00:00:00+00:00" } ] 在这种情况下它不会删除 lastUpdate 键。
  • 问题是,在执行函数之前我并不完全知道 json 的架构。
  • $key 变量重叠,我的错。请参阅我编辑的答案。
  • 顺便说一句,我的NOTE 评论中的问题只有在您使用数字作为删除键时才会出现
  • 好的,谢谢。当我尝试删除 latestVersion 时,它似乎并没有为此模式取消设置:[ { "id": 1, "name": "oyzignasasady647", "status": "active", "latestVersion": "8.9.8", "description": "this is a desc", "descriptionShort": "shortDesc", "contacts": [ "\/api\/contacts\/2" ] }, { "id": 2, "name": "ueflasaslqc883", "status": "inactive", "latestVersion": "0.8.0", "description": "desc", "descriptionShort": "shortdesc", "contacts": [ "\/api\/contacts\/18" ] } ]
猜你喜欢
  • 2014-02-25
  • 2013-11-09
  • 1970-01-01
  • 1970-01-01
  • 2016-11-13
  • 1970-01-01
  • 1970-01-01
  • 2021-01-20
相关资源
最近更新 更多