【问题标题】:Is there a way to remove all repeated keys except the last one in array?有没有办法删除除了数组中的最后一个键之外的所有重复键?
【发布时间】:2026-02-22 23:10:01
【问题描述】:

我从服务器收到了一系列消息,其中包含用户看到消息的键 seen_by,它的结构:

[1] => Array
    (
        [seen_by] => Array
            (
                [1] => user_1
                [2] => user_2
                [3] => user_3
            )

    )

[2] => Array
    (
        [seen_by] => Array
            (
                [2] => user_2
                [3] => user_3
            )

    )
[3] => Array
    (
        [seen_by] => Array
            (
                [3] => user_3
            )

    )

他们在 seen_by 数组中的键是 user_id,

我想要做的是因为 user_2 已经在第二条消息的 seen_by 数组中,所以从第一个 seen_by 数组中删除它,并且因为 user_3 在 >seen_by 第三条消息数组,从前两条消息中删除

我想得到类似的数组

[1] => Array
    (
        [seen_by] => Array
            (
                [1] => user_1
            )

    )

[2] => Array
    (
        [seen_by] => Array
            (
                [2] => user_2
            )

    )
[3] => Array
    (
        [seen_by] => Array
            (
                [3] => user_3
            )

    )

【问题讨论】:

  • 如果 user_2 看到消息 1 和 2,为什么要从消息 1 中删除 user_2?这不是意味着 user_2 没有看到消息 1,而只看到了消息 2?如果这些数组实际上代表相同的消息,那么为什么不将用户合并到一个数组中呢?
  • @DaveS 不,我实际上想做类似 messenger 的事情,所以当消息下的用户图标表示他看到了之前的所有内容时,这些数组中的每一个都代表消息,并且还有其他键,例如消息时间,发件人的姓名等,但我将它们修剪为专注于 seen_by 键

标签: php arrays


【解决方案1】:

使用 foreach 循环并从最后一个循环到第一个循环。为此,请使用array_reverse()。使用$set 使用isset 检查用户是否已被跟踪。如果是,则从当前子数组unset 或将其添加到$set 并与下一个元素一起移动。最后再写一个array_reverse,只是为了恢复原来的顺序。

片段:

<?php

function removeDups($data){
    $set = [];
    $res = [];
    foreach(array_reverse($data) as &$sub){
        foreach($sub['seen_by'] as $idx => $val){
            if(isset($set[ $val ])){
                unset($sub['seen_by'][ $idx ]);
            }else{
                $set[ $val ] = true; 
            }
        }
        $res[] = $sub;
    }
    return array_reverse($res);
}

print_r(removeDups($data));

Online Demo

【讨论】:

    【解决方案2】:

    我已经简化了数组以进行说明,但显示了这个想法。您可以从末尾开始循环遍历数组并向后工作,删除后面数组中存在的元素。

    $array = array(
        array( 1, 2, 3 ),
        array( 2, 3 ),
        array( 3 ),
    );
    $len = count( $array );
    for ( $i = $len -1 ; $i > 0; $i-- ) {
        $curr_array = $array[ $i ];
        for( $j = $i - 1; $j >= 0; $j-- ) {
            $array[$j] = array_diff( $array[$j], $curr_array );
        }
    }
    

    【讨论】: