0

in my symfony project, I need to be able to merge several arrays of objects while removing duplicates.

For example :

array 1 :

Array
(
    [0] => Absence Object
        (
            [id] => 1
            [type] => TypeConge Object ([id] => 4, [nom] => "Maladie")
            [user] => User Object (......)
            [debut] => 12-11-2019 00:00:00
        )

    [1] => Absence Object
        (
            [id] => 2
            [type] => TypeConge Object ([id] => 5, [nom] => "CA")
            [user] => User Object (......)
            [debut] => 13-11-2019 00:00:00
        )

    [2] => Absence Object
        (
            [id] => 3
            [type] => TypeConge Object ([id] => 4, [nom] => "Maladie")
            [user] => User Object (......)
            [debut] => 11-11-2019 00:00:00
        )    
)

Array 2:

Array
(
    [0] => Absence Object
        (
            [id] => 1
            [type] => TypeConge Object ([id] => 4, [nom] => "Maladie")
            [user] => User Object (......)
            [debut] => 12-11-2019 00:00:00
        )

    [1] => Absence Object
        (
            [id] => 8
            [type] => TypeConge Object ([id] => 4, [nom] => "Maladie")
            [user] => User Object (......)
            [debut] => 17-11-2019 00:00:00
        )    
)

output:

    Array
(
    [0] => Absence Object
        (
            [id] => 1
            [type] => TypeConge Object ([id] => 4, [nom] => "Maladie")
            [user] => User Object (......)
            [debut] => 12-11-2019 00:00:00
        )

    [1] => Absence Object
        (
            [id] => 2
            [type] => TypeConge Object ([id] => 5, [nom] => "CA")
            [user] => User Object (......)
            [debut] => 13-11-2019 00:00:00
        )

    [2] => Absence Object
        (
            [id] => 3
            [type] => TypeConge Object ([id] => 4, [nom] => "Maladie")
            [user] => User Object (......)
            [debut] => 11-11-2019 00:00:00
        )    
    [3] => Absence Object
        (
            [id] => 8
            [type] => TypeConge Object ([id] => 4, [nom] => "Maladie")
            [user] => User Object (......)
            [debut] => 17-11-2019 00:00:00
        )    

)

I use this code to do it :

$demandes = $this->getDemandesValidateur($unUser, $search, $superValidation);
$tabDemandes = array_merge($tabDemandes, $demandes);
$tabDemandes = array_map("unserialize", array_unique(array_map("serialize", $tabDemandes)));

But I get the impression that it causes bugs because of serialization and deserialization. I get the good final table, but some data seems unusable. For example I can not call:

$absence->getType()->getNom();

It returns null sometimes. Is it because of my code ?

My case :

To clarify my case, here's what I'm supposed to do:

I have an empty board at the beginning. Then I make a loop to retrieve other tables that I merge. And in the end, I remove the duplicates.

It looks like this:

                case "ROLE_SUPPLEANT":
                    $tabDemandes = [];
                    $users = $this->repoUsers->getUsersWhereIsSuppleant($user);

                    foreach($users as $unUser)
                    {
                        $demandes = array_column($this->getDemandesCongesForCalendar($unUser, $demandesConges, "ROLE_VALIDATEUR"), null, 'id');
                        $tabDemandes = $tabDemandes + $demandes;
                    }
                    if($user->hasRole("ROLE_VALIDATEUR"))
                    {
                        $demandes = array_column($this->getDemandesCongesForCalendar($user, $demandesConges, "ROLE_VALIDATEUR"), null, 'id');
                        $tabDemandes = $tabDemandes + $demandes;
                    }
                    break;

Knowing that the function getDemandesCongesForCalendar () returns an array of objects (which themselves contain objects).

I have the impression of having misused the code that you advised me, because it will not remove duplicates I think at the end. The variable $ requests will in any case contain an array with unique values, there will be no duplicates. But since each time, I add its values to the general table ($ tabDemands), there may be duplicates in the latter. And that's where I should step in to remove duplicates

eronn
  • 1,690
  • 3
  • 21
  • 53
  • does each id can be present in any array only once? – splash58 Nov 26 '19 at 20:21
  • Yes, but at the end, I can have many times the same identifiant so I have to delete the duplicates. ( Sorry for the english I'm french ) – eronn Nov 26 '19 at 20:30
  • array_column(array, null,'id') will make id's as index for arrays. Than you can merge them by a usual loop – splash58 Nov 26 '19 at 20:35

2 Answers2

1

Based on splash58's comment, you can use array_column() and then merge arrays while keeping only the first item. A sample can be seen here.

<?php

$records = array(
    array(
        'id' => 2135,
        'first_name' => 'John',
        'last_name' => 'Doe',
    ),
    array(
        'id' => 3245,
        'first_name' => 'Sally',
        'last_name' => 'Smith',
    ),
    array(
        'id' => 5342,
        'first_name' => 'Jane',
        'last_name' => 'Jones',
    ),
    array(
        'id' => 5623,
        'first_name' => 'Peter',
        'last_name' => 'Doe',
    )
);

$records2 = array(
    array(
        'id' => 2135,
        'first_name' => 'John',
        'last_name' => 'Doe',
    ),
    array(
        'id' => 3245,
        'first_name' => 'Sally',
        'last_name' => 'Smith',
    ),
    array(
        'id' => 5342,
        'first_name' => 'Jane',
        'last_name' => 'Jones',
    ),
    array(
        'id' => 5624,
        'first_name' => 'Peter',
        'last_name' => 'Doe',
    )
);

$first = array_column($records, null, 'id');
$second = array_column($records2, null, 'id');
$third = $first + $second;

// if you want to reset indexes
// $third = array_values($third);

echo print_r($third);
Vladan
  • 1,572
  • 10
  • 23
0

You can do something like this:

$result = [];

$array1 = [
  [
    "id" => 1,
    "other_data" => "text1"
  ],
  [
    "id" => 2,
    "other_data" => "text2"
  ],
  [
    "id" => 3,
    "other_data" => "text3"
  ],  
];

$array2 = [
  [
    "id" => 1,
    "other_data" => "text1"
  ],
  [
    "id" => 8,
    "other_data" => "text8"
  ],
];

$merge_array = function($array, $result) {
  foreach($array as $element) {
      $id = $element["id"]; //In your case it could be $element->getId()
      if(!isset($result[$id])) { 
         $result[$id] = $element;
      }
  }

  return $result;
};

$result = $merge_array($array1, $result);
$result = $merge_array($array2, $result);
print_r(array_values($result));
Pipe
  • 2,379
  • 2
  • 19
  • 33