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