删除关联数组中的键无效

3

我正在尝试保留特定的键,并从外部API中删除其余的键。我有一个包含对象的数组(http://pastebin.com/vU8T4y7h),名为"data":

foreach ($data as $media) {
    foreach (array_keys($media) as $media_key) {
        if ($media_key!=="created_time" && $media_key!=="likes" && $media_key!=="images" && $media_key!=="id") {
            unset($media[$media_key]);
        }
    }
}

在这种情况下,我试图只保留“created_time”,“likes”,“images”和“id”键,但上面的代码不起作用。有什么想法吗?是否有其他更优雅的解决方案来实现同样的目标?
5个回答

9
这不起作用的原因是因为您没有从原始的$data对象中取消设置。您可以通过两种方法解决这个问题。要么使用引用访问,要么更新您的unset以便作用于原始的$data对象。
使用引用:
foreach($data as &$media) {

$data中取消设置

unset($data[$media][$media_key]);

1

foreach 循环会创建每个数组元素的副本,因此取消设置 $media[$media_key] 只会从副本中取消设置;而您想要从原始的 $data 数组中取消设置:

foreach ($data as $mediaRef => $media) {
    foreach (array_keys($media) as $media_key) {
        if ($media_key!=="created_time" && $media_key!=="likes" && $media_key!=="images" && $media_key!=="id") {
            unset($data[$mediaRef][$media_key]);
        }
    }
}

或(通过引用)

foreach ($data as &$media) {
    foreach (array_keys($media) as $media_key) {
        if ($media_key!=="created_time" && $media_key!=="likes" && $media_key!=="images" && $media_key!=="id") {
            unset($media[$media_key]);
        }
    }
}
unset($media);

在从原始数据源删除时,需要使用foreach k,v而不是仅使用value进行第一次迭代。 - sberry

1

您可以使用array_intersect_key轻松地完成这种操作:

$keepTheseKeys = array_flip(array('created_time', 'likes', 'images', 'id'));

foreach ($data as &$media) {
    $media = array_intersect_key($media, $keepTheseKeys);
}
unset($media);

错误

问题代码中的错误在于您正在更新一个临时变量,要么通过引用传递媒体(请参见上面的示例),要么引用原始变量:

foreach ($data as $i => $media) {
    $data[$i] = ...

我认为你想要使用 array_intersect_key 而不是 array_diff_key - NullUserException
我确实这么做了 @NullUserException - AD7six
你也想在循环后使用 unset($media) - Sven
@Sven 只有在重复使用引用时才很重要,而这是一个糟糕的想法。 - AD7six
我认为在foreach中使用引用首先是一件可怕的事情,但因人而异。 - Sven

1

请求一个优美的解决方案:

foreach ($data as $key => $media) {
    foreach (array_keys($media) as $media_key) {
        if (!in_array($media_key, array("created_time", "likes", "images", "id"))) {
            unset($data[$key][$media_key]);
        }
    }
}

我会尽量避免在foreach循环中使用引用,因为你需要取消引用变量。如果不这样做,就会出现难以检测的错误。


0
首先,你不需要使用


foreach (array_keys($media) as $media_key) {

你可以使用

foreach($media as $media_key => $media_value){

相反

但是对于你的问题,在第一行中,你正在遍历 $data,并且在每个循环中,将 $data 中的当前值分配给 $media。但是 $media 没有任何与原始 $data 的连接,因此在下一次迭代时被丢弃,当新值从 $data 分配到 $media 时。

你有两个选择:

  1. 使用引用:

    foreach($data as &$media) { // 等等... 这应该可以工作,但我不建议这样做
    
  2. 在第一行中,写入

    foreach($data as $media_k => $media) {
    

    并在第四行中,写入

    unset($data[$media_k][$media_key]); //
    

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