【问题标题】:How do you remove arrays containing a string from an object?如何从对象中删除包含字符串的数组?
【发布时间】:2016-01-11 22:15:22
【问题描述】:

抱歉,我什至不太清楚如何表达我的问题。

我正在尝试使用奇怪的设置从公共 JSON API 中删除个人注册信息。示例:

"posts" : [
  {
  "id": 9658,
  "type": "event",
  "custom_fields" : {
    "registered_person_0_name" : [ "John" ],
    "registered_person_1_name" : [ "Doe" ]
  } 

如果有帮助,这是var_dump:

["custom_fields"]=>
  object(stdClass)#6601 (45) {
    ["registered_person_0_name"]=>
      array(1) {
        [0]=> string(8) "Beverley"
      }

根据事件的不同,注册人的数量未知,并且每个字段都会增加,如图所示。我想我会 unset() 所有“registered_person”实例,但我很难过。

如果给定$posts,我觉得我可以这样做:

foreach ( $posts as $post ) {
  unset( $post->custom_fields->all_the_registered_persons_fields_that_match)
}

但我想不通。我尝试将custom_fields 对象类型转换为数组并使用in_array,然后使用unset,但这似乎不起作用。

感谢任何指点。如果我能提供更多信息,请告诉我。

【问题讨论】:

  • 这肯定是一个组织不良的数据结构
  • 您要删除只是registered_person_0_name, registered_person_1_name..... 还是整个custom_fields
  • 肯定是:/ @RiggsFolly。我想删除registered_person_#_name ...但保留自定义字段。 FWIW 这是一个旧的 WordPress JSON API。

标签: php arrays json object


【解决方案1】:

遍历属性变量,如果它们匹配模式则取消设置。

foreach ($posts as $post) {
    $custom_fields = $post->custom_fields;
    foreach (get_object_vars($custom_fields) AS $name => $val) {
        if (preg_match('/^registered_person_\d+_name$/', $name)) {
            unset($custom_fields->{$name});
        }
    }
}

另一种选择是使用json_decode() 的可选参数,以便它返回关联数组而不是对象。然后你可以在数组上使用foreach。

foreach ($posts as &$post) {
    $custom_fields = &$post['custom_fields'];
    foreach ($custom_fields AS $name => $val) {
        if (preg_match('/^registered_person_\d+_name$/', $name)) {
            unset($custom_fields[$name]);
        }
    }
}

请注意,在这种情况下,您必须使用引用变量,因为分配数组通常会产生副本。

【讨论】:

  • 谢谢@Barmar。我想我已经接近了这一点,但get_object_vars 完全是关键。我很感激!
  • 您也可以使用json_encode 的选项返回数组而不是对象。
【解决方案2】:

假设您有一个包含要删除的字段的数组,您可以使用->{$propName} 来实现此目的。 ->{$someVar} 允许您动态访问对象的属性。

例如:

$field1 = "name";
echo($object->{$field}) // will echo the name property

在你的情况下:

$sensibleFields = ['creditCardNumber', 'socialSecurityNumber'];
foreach ($posts as $post) {
    foreach ($sensibleFields as $fieldName) {
        unset($post->{$fieldName});
    }
}

【讨论】:

  • 谢谢@cristik。我之前对->{$someVar} 有点远见,但不了解它的用途。
【解决方案3】:

如果您使用json_decode($the_api_data, true) 获取结果数组样式而不是对象样式,则可以使用array_filter 删除不需要的键。

foreach ($posts as &$post) {  // need to use a reference here for this to work
    $post['custom_fields'] = array_filter($post['custom_fields'], function($key){
        return 'registered_person_' != substr($key, 0, 18);
    }, ARRAY_FILTER_USE_KEY);
}

【讨论】:

    猜你喜欢
    • 2018-10-06
    • 2021-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-25
    • 2020-06-01
    • 1970-01-01
    相关资源
    最近更新 更多