I Have some problem with some value on array at php, here is the array
array:4 [
0 => array:7 [
"id" => 76
"id_sender" => 1
"id_receiver" => 2
"message" => "2 Miliar"
"is_read" => 0
"created_at" => "2022-11-28T13:57:17.000000Z"
"updated_at" => "2022-11-28T13:57:17.000000Z"
]
1 => array:7 [
"id" => 75
"id_sender" => 1
"id_receiver" => 3
"message" => "1 Miliar"
"is_read" => 0
"created_at" => "2022-11-28T13:57:10.000000Z"
"updated_at" => "2022-11-28T13:57:10.000000Z"
]
2 => array:7 [
"id" => 74
"id_sender" => 3
"id_receiver" => 1
"message" => "Property ini berapa harganya?"
"is_read" => 1
"created_at" => "2022-11-28T13:52:57.000000Z"
"updated_at" => "2022-11-28T13:55:37.000000Z"
]
3 => array:7 [
"id" => 73
"id_sender" => 2
"id_receiver" => 1
"message" => "Untuk yang ini berapa harganya?"
"is_read" => 1
"created_at" => "2022-11-28T13:07:34.000000Z"
"updated_at" => "2022-11-28T13:55:33.000000Z"
]
]
That’s my array, I want to skip the the value on index 2 and 3 because I’ve already the value
for example
id_sender = 1 && id_receiver = 3,
because on index 2 i already have value, even it is reverse
id_sender = 3 && id_receiver = 1,
that’s put on check of id_receiver of index 2, and another conditions and so one,
the result i want are like this
array:2 [
0 => array:7 [
"id" => 76
"id_sender" => 1
"id_receiver" => 2
"message" => "2 Miliar"
"is_read" => 0
"created_at" => "2022-11-28T13:57:17.000000Z"
"updated_at" => "2022-11-28T13:57:17.000000Z"
]
1 => array:7 [
"id" => 75
"id_sender" => 1
"id_receiver" => 3
"message" => "1 Miliar"
"is_read" => 0
"created_at" => "2022-11-28T13:57:10.000000Z"
"updated_at" => "2022-11-28T13:57:10.000000Z"
]
]
How can I solve that in php?
** EDIT **
I tried using array_filter, but it didn’t change anything:
$member1 = 1;
$member2 = 3;
array_filter($items_message, function($v, $k) use ($member1, $member2) {
return (($k == 'id_sender' && $v == $member1) && ($k == 'id_receiver' && $v == $member2 )) || (($k == 'id_sender' && $v == $member2) && ($k == 'id_receiver' && $v == $member1 ));
}, ARRAY_FILTER_USE_BOTH);
2
Answers
First you need to find a way to know what you’ve seen so far while looping through your array.
A solid solution would be to use a pairing function, to create some unique number out of the 2 numbers you have. Pairing functions do not give the same result if the numbers are inverted, so we’ll need to make sure we feed both numbers in the same order, to do that we’ll use the smallest number of the two first. You’d then be able to easily determine if you already encountered the pair.
I am sorry my PHP is very rusty, so I’ll use something similar but the code won’t work.
You would then loop through your array, take the return of this "almost" cantor pair (almost because we switch the numbers as explained above). You’d check if you have it in an array, if not you push the object to your result array and add that pair to your "known" array. If you find a pair, then you simply ignore the object.
About pairing function, Wikipedia sums it up very well:
While iterating, isolate the sender and receiver ids as a temporary array, sort the two elements, then implode them as a string — this will give you a reliable value to use as the key in result array. With these new associative first-level keys in your result array, you can use the null coalescing assignment operator to only store the first occurring row for each respective id set.
Code: (Demo)
If you prefer a classic loop to iterate, then this is equivalent to the above snippet (Demo)
Relevant reading: Filter/Remove rows where column value is found more than once in a multidimensional array