1

I am working with an API that brings back holiday data for employees. The data contains approved holiday requests, as well as cancelled holiday requests. The problem I am facing, is that cancelled holiday requests show up as duplicate entries in the following format:

stdClass Object
  (
     [leave_requests] => Array
     (
        [0] => stdClass Object
            (
                [employee] => stdClass Object
                    (
                        [id] => 30771
                    )

                [reviewed_by] => stdClass Object
                    (
                        [id] => 22734
                    )

                [reason] => 
                [type] => Holiday
                [deducted] => 1.0
                [cancelled] => 
                [id] => 626214
                [start_date] => 2015-08-20
                [half_start] => 
                [half_start_am_pm] => 
                [end_date] => 2015-08-20
                [half_end] => 
                [half_end_am_pm] => 
                [action] => request
                [status] => approved
                [notes] => 
                [created_at] => 2015-08-06T21:55:12+01:00
                [updated_at] => 2015-08-07T08:26:07+01:00
            )

        [1] => stdClass Object
            (
                [employee] => stdClass Object
                    (
                        [id] => 30771
                    )

                [reviewed_by] => stdClass Object
                    (
                        [id] => 22734
                    )

                [reason] => 
                [type] => Holiday
                [deducted] => 1.0
                [cancelled] => 
                [id] => 632745
                [start_date] => 2015-08-20
                [half_start] => 
                [half_start_am_pm] => 
                [end_date] => 2015-08-20
                [half_end] => 
                [half_end_am_pm] => 
                [action] => cancel
                [status] => approved
                [notes] => 
                [created_at] => 2015-08-12T17:50:32+01:00
                [updated_at] => 2015-08-12T17:53:46+01:00
            )

    )
)

Ideally the data would be formatted so that the cancelled property is utilized and I could filter off that (this has been requested of the developers). What I would like to do is remove both entries that have the same start_date and end_date.

Currently I am able to remove the duplicate, by using this function

function super_unique($array)
    {
        $newArr = array();
        foreach ($array as $val) {
            $newArr[$val['startDate']] = $val;
        }
        $array = array_values($newArr);

        return $array;
    }

Couple of problems with this, in that I am still left with one of the entries, as the holiday request has been cancelled I don't want either of them in the data. Filtering the data to exclude all elements that have the action property of 'cancel' will still leave me with the original request as well.

The other problem is that the above function is only filtering based off start_date and not both start_date and end_date.

Had a look through the comments on this SO question, and in the comments on the PHP doc page for array_values and array_unique.

Community
  • 1
  • 1
terrorfall
  • 1,121
  • 3
  • 16
  • 33

1 Answers1

1

I have made some slight modifications to your current code, please see comments in the code:

function super_unique($array)
{
    $newArr = array();

    foreach ($array as $val) {
        // Create a key by combining start/end dates 
        $key = $val['startDate'].$val['endDate'];

        // Have we already seen this start/end date combination?
        if (array_key_exists($key, $newArr)) {
            $val = null; // Clear element value, like "remove this later on"
        }
        $newArr[$key] = $val; // Add to/update key index (actual value or null)
    }

    // Remove all elements with unset (null) values
    $array = array_filter(array_values($newArr));

    return $array;
}

$a = [['startDate' => '2015-08-20', // Exists twice - should be removed
       'endDate'   => '2015-08-22'],
      ['startDate' => '2015-08-20', // Unique start/end combination
       'endDate'   => '2015-08-20'],
      ['startDate' => '2015-08-21', // Unique start/end combination
       'endDate'   => '2015-08-21'],
      ['startDate' => '2015-08-20', // Exists twice - should be removed
       'endDate'   => '2015-08-22'],
      ['startDate' => '2015-08-22', // Unique start/end combination
       'endDate'   => '2015-08-20'],
];

print_r(super_unique($a));

Output:

Array
(
    [1] => Array
        (
            [startDate] => 2015-08-20
            [endDate] => 2015-08-20
        )

    [2] => Array
        (
            [startDate] => 2015-08-21
            [endDate] => 2015-08-21
        )

    [3] => Array
        (
            [startDate] => 2015-08-22
            [endDate] => 2015-08-20
        )
)
mhall
  • 3,671
  • 3
  • 23
  • 35