0

I build an array over a loop, so each object in my array are build the same way with the same key and same data type. My array looks like this :

$array_of_obj = array(
    0 => {
        date: "2017-11-26"
        hour_array: Array [ "11:00:00", "12:00:00", "13:00:00", … ]
        id_pb: "32"
        id_slot_pb: "704"
    },
    1 => {
        date: "2017-11-26"
        hour_array: Array [ "11:00:00", "12:00:00", "13:00:00", … ]
        id_pb: "32"
        id_slot_pb: "704"
    },
    2 => {
        date: "2017-11-27"
        hour_array: Array [ "11:00:00", "12:00:00", "13:00:00", … ]
        id_pb: "32"
        id_slot_pb: "705"
    },
    3 => {
        date: "2017-11-27"
        hour_array: Array [ "11:00:00", "12:00:00", "13:00:00", … ]
        id_pb: "32"
        id_slot_pb: "705"
    },
    4 => {
        date: "2017-11-28"
        hour_array: Array [ "11:00:00", "12:00:00", "13:00:00", … ]
        id_pb: "32"
        id_slot_pb: "706"
    },
    // etc. 
);

So I have an array with multiple identical object, and I'd like to have unique object in my big array.

I find this solution :

How do I use array_unique on an array of arrays?

So it was perfect, even if it was with array of array I think it could work. I test it with the two best anwser I find :

$array_of_obj = array_intersect_key($array_of_obj, array_unique(array_map('serialize', $array_of_obj)));

AND

$array_of_obj = array_intersect_key($array_of_obj, array_unique(array_map(function ($el) {
    return $el['id_slot_pb'];
}, $array_of_obj)));

And I have the SAME result for both :

$array_of_obj = array(
    0: Object { id_slot_pb: "704", id_pb: "32", date: "2017-11-26", … }
    4: Object { id_slot_pb: "706", id_pb: "32", date: "2017-11-28", … },
    6: Object { id_slot_pb: "707", id_pb: "32", date: "2017-11-29", … },
    8: Object { id_slot_pb: "708", id_pb: "32", date: "2017-11-30", … },
    //etc
);

As you can see he skipped the object with key = 2 or 3 (both are the same) and go from 0 to 4... I made more test building my "array_of_obj" with more duplicate (I had the same structure but with 5 by 5 identicals object and he still skipped the same data.

I tried to check where is my error, so I only do this :

$array_of_obj = array_map('serialize', $array_of_obj);

It was ok, I had an array of string now with same result (key 0 and 1 the same, 2 and 3 the same, 4 and 5, etc.)

But when I used array_unique I lost the key 2 and 3 as I said :

$array_of_obj = array_unique(array_map('serialize', $array_of_obj));

I made a little test to check if the data were considered as identical by array_unique even if it's not the case :

$array_of_obj = array_map('serialize', $array_of_obj);

$test = array();
    $string_test = "";
    foreach($array_of_obj as $array) {
        if ($string_test !== $array) {
            $string_test = $array;
            $test[] = $array;
        }
}

But with this it worked, I had all the unique data serialized in my $test array.

I can't understand why it works for ALL the other object but the same data are just skipped or considered as identical as other even if it's not true...if someone have some clue or a logical explaination it would be nice, thanks !

Mickaël Leger
  • 3,426
  • 2
  • 17
  • 36
  • Can you post your exactly array of objects and not the bad formatted array? I just try in phpfiddle and work perfectly in both cases – Alberto Favaro Nov 24 '17 at 15:27
  • The code is in a PHP script I called in an Ajax function, so I check the data with a "console.log(response)". The "bad formatted array" (the one with the result I think?) is the copy/paste of my console and he is identical as the first I post, without the duplicate and the data with "id_slot_pb : 705" as I said. Could it be a visualisation problem if it works for you? – Mickaël Leger Nov 24 '17 at 15:41
  • Just edited the answer – Alberto Favaro Nov 24 '17 at 16:28

2 Answers2

0

Your each test on array of string serialized not work if the objects of your array are not ordered by id_slot_pb or date keys. If you paste this code test that i tried on PHP fiddle it work perfectly:

<pre>
<?php

$array = [
    (object)[
        'date' => '2017-11-26',
        'hour_array' => ['11:00:00', '12:00:00', '13:00:00'],
        'id_pb' => '32',
        'id_slot_pb' => '704'
    ],
    (object)[
        'date' => '2017-11-26',
        'hour_array' => ['11:00:00', '12:00:00', '13:00:00'],
        'id_pb' => '32',
        'id_slot_pb' => '704'
    ],
    (object)[
        'date' => '2017-11-27',
        'hour_array' => ['11:00:00', '12:00:00', '13:00:00'],
        'id_pb' => '32',
        'id_slot_pb' => '705'
    ],
    (object)[
        'date' => '2017-11-27',
        'hour_array' => ['11:00:00', '12:00:00', '13:00:00'],
        'id_pb' => '32',
        'id_slot_pb' => '705'
    ],
    (object)[
        'date' => '2017-11-28',
        'hour_array' => ['11:00:00', '12:00:00', '13:00:00'],
        'id_pb' => '32',
        'id_slot_pb' => '706'
    ],
    (object)[
        'date' => '2017-11-28',
        'hour_array' => ['11:00:00', '12:00:00', '13:00:00'],
        'id_pb' => '32',
        'id_slot_pb' => '706'
    ],
];

$array = array_map('serialize', $array);

$yourTest = $myTest = [];
$stringTest = "";
foreach($array as $key => $serialized) {
    if(!in_array($serialized, $myTest)){
        $myTest[$key] = $serialized;    
    }

    if ($stringTest !== $serialized) {
        $stringTest = $serialized;
        $yourTest[] = $serialized;
    }
}

//your test
var_dump($yourTest);

//my test
var_dump($myTest);

//array unique
$array = array_unique($array);
var_dump($array);

?>

</pre>

Results:

Your test (that not work as i said if not ordered)

 array(3) {
  [0]=>
  string(178) "O:8:"stdClass":4:{s:4:"date";s:10:"2017-11-26";s:10:"hour_array";a:3:{i:0;s:8:"11:00:00";i:1;s:8:"12:00:00";i:2;s:8:"13:00:00";}s:5:"id_pb";s:2:"32";s:10:"id_slot_pb";s:3:"704";}"
  [1]=>
  string(178) "O:8:"stdClass":4:{s:4:"date";s:10:"2017-11-27";s:10:"hour_array";a:3:{i:0;s:8:"11:00:00";i:1;s:8:"12:00:00";i:2;s:8:"13:00:00";}s:5:"id_pb";s:2:"32";s:10:"id_slot_pb";s:3:"705";}"
  [2]=>
  string(178) "O:8:"stdClass":4:{s:4:"date";s:10:"2017-11-28";s:10:"hour_array";a:3:{i:0;s:8:"11:00:00";i:1;s:8:"12:00:00";i:2;s:8:"13:00:00";}s:5:"id_pb";s:2:"32";s:10:"id_slot_pb";s:3:"706";}"
}

My test

array(3) {
  [0]=>
  string(178) "O:8:"stdClass":4:{s:4:"date";s:10:"2017-11-26";s:10:"hour_array";a:3:{i:0;s:8:"11:00:00";i:1;s:8:"12:00:00";i:2;s:8:"13:00:00";}s:5:"id_pb";s:2:"32";s:10:"id_slot_pb";s:3:"704";}"
  [2]=>
  string(178) "O:8:"stdClass":4:{s:4:"date";s:10:"2017-11-27";s:10:"hour_array";a:3:{i:0;s:8:"11:00:00";i:1;s:8:"12:00:00";i:2;s:8:"13:00:00";}s:5:"id_pb";s:2:"32";s:10:"id_slot_pb";s:3:"705";}"
  [4]=>
  string(178) "O:8:"stdClass":4:{s:4:"date";s:10:"2017-11-28";s:10:"hour_array";a:3:{i:0;s:8:"11:00:00";i:1;s:8:"12:00:00";i:2;s:8:"13:00:00";}s:5:"id_pb";s:2:"32";s:10:"id_slot_pb";s:3:"706";}"
}

Array unique

array(3) {
  [0]=>
  string(178) "O:8:"stdClass":4:{s:4:"date";s:10:"2017-11-26";s:10:"hour_array";a:3:{i:0;s:8:"11:00:00";i:1;s:8:"12:00:00";i:2;s:8:"13:00:00";}s:5:"id_pb";s:2:"32";s:10:"id_slot_pb";s:3:"704";}"
  [2]=>
  string(178) "O:8:"stdClass":4:{s:4:"date";s:10:"2017-11-27";s:10:"hour_array";a:3:{i:0;s:8:"11:00:00";i:1;s:8:"12:00:00";i:2;s:8:"13:00:00";}s:5:"id_pb";s:2:"32";s:10:"id_slot_pb";s:3:"705";}"
  [4]=>
  string(178) "O:8:"stdClass":4:{s:4:"date";s:10:"2017-11-28";s:10:"hour_array";a:3:{i:0;s:8:"11:00:00";i:1;s:8:"12:00:00";i:2;s:8:"13:00:00";}s:5:"id_pb";s:2:"32";s:10:"id_slot_pb";s:3:"706";}"
}

Look with your eyes.

Alberto Favaro
  • 1,824
  • 3
  • 21
  • 46
0

Ok so I think I know why I had this problem (but I still don't know why).

The "Mozilla" and "Chrome" console I used to check my data both have different result. With Mozilla I have some data missing when with Chrome everything is okay (I cleared my cache to do the test).

So I think I have my anwser : it works fine, I have no problem !

But now other question : why since Moizilla update their browser I have trouble?

I will now use Chrome but this bug is very annoying.

Mickaël Leger
  • 3,426
  • 2
  • 17
  • 36