Search code examples
phparraysmergecomparisonbucket

Show what could be merged, is empty, and exists in one array


I'm trying to take two records from a table and compare them to determine what could be considered as a merge conflict, what needs to be ignored, and what can be automatically merged with no conflicts.

I have a clients table and would like to do the following:

  • client one and client two are empty - ignore
  • one client has data - ok to merge into one
  • both clients have data - let user decide

I'd like to take this information and pass it to a view where I can show controls to let the user decide what to do.

I've come up with the following, but I'm not very good with PHP's array functions and might be able to utilize something better or more efficient?

$results = [];
foreach ($client_first as $key => $value){
    if (empty($value) && empty($client_second[$key])) {
        $results['ignore'][] = $key;
    } elseif (!empty($value) && empty($client_second[$key])) {
        $results['merged'][$key] = $value ? $value : $client_second[$key];
    } elseif (empty($value) && !empty($client_second[$key])) {
        $results['merged'][$key] = $value ? $value : $client_second[$key];  
    } elseif (!empty($value) && !empty($client_second[$key])) {
        $results['conflicts'][] = $key;
    }
}

I'm not married to the above. So, any suggestions would be welcome.

The two arrays would be something like:

First array:

array:8 [
  first_name => "John"
  last_name => "Doe"
  middle_initial => null
  email => null
  cell_phone => null
  education_level => null
  gender => "Male"
  race => "White"
]

Second array:

array:8 [
  first_name => "Johnn"
  last_name => "Does"
  middle_initial => null
  email => null
  cell_phone => null
  education_level => null
  gender => null
  race => null
]

And I would expect to see:

array:3 [
  "conflicts" => array:2 [
    0 => "last_name"
    1 => "first_name"
  ]
  "ignore" => array:4 [
    0 => "middle_initial"
    1 => "email"
    2 => "cell_phone"
    3 => "education_level"
  ]
  "merged" => array:2 [
    "gender" => "Male"
    "race" => "White"
  ]
]

Solution

  • Input:

    $a1=[
      'first_name' => "John",
      'last_name' => "Doe",
      'middle_initial' => null,
      'email' => null,
      'cell_phone' => null,
      'education_level' => null,
      'gender' => "Male",
      'race' => "White"
    ];
    $a2=[
      'first_name' => "Johnn",
      'last_name' => "Does",
      'middle_initial' => null,
      'email' => null,
      'cell_phone' => null,
      'education_level' => null,
      'gender' => null,
      'race' => null
    ];
    

    Method:

    $result=["conflicts"=>[],"ignore"=>[],"merged"=>[]];    
    foreach($a1 as $k=>$v){
        if($v==$a2[$k]){                       // no change, ignore
            $result["ignore"][]=$k;
        }elseif(is_null($v)){                  // yes change, 1st is null, use 2nd
            $result["merged"][$k]=$a2[$k];
        }elseif(is_null($a2[$k])){             // yes change, 2nd is null, use 1st
            $result["merged"][$k]=$v;
        }else{                                 // neither are null, user decides
            $result["conflicts"][]=$k;
        }
    }
    var_export($result);
    

    Output:

    array (
      'conflicts' => 
      array (
        0 => 'first_name',
        1 => 'last_name',
      ),
      'ignore' => 
      array (
        0 => 'middle_initial',
        1 => 'email',
        2 => 'cell_phone',
        3 => 'education_level',
      ),
      'merged' => 
      array (
        'gender' => 'Male',
        'race' => 'White',
      ),
    )
    

    Additionally, you could store the actual conflicts by using:

    $result["conflicts"][]=["field"=>$k,"firstvalue"=>$v,"secondvalue"=>$a2[$k]];
    

    in the else block. This would give you a conflicts subarray like this:

    'conflicts' => array (
        0 => array (
          'field' => 'first_name',
          'firstvalue' => 'John',
          'secondvalue' => 'Johnn',
        ),
        1 => array (
          'field' => 'last_name',
          'firstvalue' => 'Doe',
          'secondvalue' => 'Does',
        )
      )
    

    This data storage structure might help you to set up the user interface.