Home > Back-end >  Is there a way to remove all repeated keys except the last one in array?
Is there a way to remove all repeated keys except the last one in array?

Time:11-22

I have array of messages received from server, with key seen_by which contain users saw the message, it's structure :

[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
            )

    )

where they keys in seen_by array is user_id,

what i want to do is since user_2 already in the seen_by array of the second message ,so remove it from the first seen_by array , and since user_3 in seen_by array of third message , remove from the first two messages

I want to get array like

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

    )

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

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

    )

CodePudding user response:

I've simplified the arrays for illustration but the idea is shown. You can loop through the arrays starting at the end and working backwards, removing elements that exist in later arrays.

$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 );
    }
}

CodePudding user response:

Use foreach loop and loop from last to first. To do so, use array_reverse(). Use a $set to check if a user is already tracked using isset. If it is, unset it from the current subarray or add it to the $set and move with the next element. An array_reverse at the end is done again just to restore the original order.

Snippet:

<?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

  • Related