Jeremy Love Jeremy Love - 4 months ago 11
PHP Question

Multidemensional array filter out duplicates within group

Im trying to remove the duplicate array value group based on the same dates(only keep 1 group).

Also take the number in the "1" key (above the pid key) and add it together with the duplicated grouped.

The issue im having is the each group under hour is "only" supposes to filter with duplicate groups under the same "hour" section.

Here's the array im starting with:

Array(
[1488] => Array
(
[hours] => Array
(
[0] => Array
(
[0] => 2016/07/11 - 2016/07/17
[1] => 37
[pid] => 1488
)

[1] => Array
(
[0] => 2016/07/04 - 2016/07/10
[1] => 51
[pid] => 1488
)

[2] => Array
(
[0] => 2016/07/04 - 2016/07/10
[1] => 44
[pid] => 1488
)

[3] => Array
(
[0] => 2016/07/04 - 2016/07/10
[1] => 22
[pid] => 1488
)

)

)

[2] => Array
(
[hours] => Array
(
[0] => Array
(
[0] => 2016/07/04 - 2016/07/10
[1] => 9.5
[pid] => 2
)

[1] => Array
(
[0] => 2016/07/04 - 2016/07/10
[1] => 8
[pid] => 2
)

[2] => Array
(
[0] => 2016/07/04 - 2016/07/10
[1] => 7
[pid] => 2
)

[3] => Array
(
[0] => 2016/07/11 - 2016/07/17
[1] => 5
[pid] => 2
)

)

)

)


Here what i need it to look like:

Array(
[0] => Array
(
[hours] => Array
(
[0] => Array
(
[0] => 2016/07/11 - 2016/07/17
[1] => 37
[pid] => 1488
)

[1] => Array
(
[0] => 2016/07/04 - 2016/07/10
[1] => 117
[pid] => 1488
)

)

)

[1] => Array
(
[hours] => Array
(
[0] => Array
(
[0] => 2016/07/04 - 2016/07/10
[1] => 24.5
[pid] => 2
)

[1] => Array
(
[0] => 2016/07/11 - 2016/07/17
[1] => 5
[pid] => 2
)

)

)

)


This is my code:

$temp_array = array();
$w = 0;
$key_array = array();

$new_array = array();

foreach($project_hours as $old_arrs) {


foreach ($old_arrs["hours"] as $val) {
if (!in_array($val[0], $key_array)) {
$key_array[$w] = $val[0];
$temp_array[$w] = $val;

} else {
$ser = array_search($val[0], $key_array);
$temp_array[$ser][1] += $val[1];
}

$w++;

$old_arrs["hours"] = $temp_array;

}


$new_array[] = $old_arrs;
}

echo '<pre>';
print_r($new_array);
echo '</pre>';

Answer

You can just do some simple tricks to organize the array keys, then use array_values() in two areas to reset the associative keys to numeric keys:

// Your array
$data = array(
     1488 => array(
        'hours' => array(
            0 => array(
                0 => '2016/07/11 - 2016/07/17',
                1 => 37,
                'pid' => 1488,
            ),
            1 => array(
                0 => '2016/07/04 - 2016/07/10',
                1 => 51,
                'pid' => 1488
            ),
            2 => array(
                0 => '2016/07/04 - 2016/07/10',
                1 => 44,
                'pid' => 1488
            ),
            3 => array(
                0 => '2016/07/04 - 2016/07/10',
                1 => 22,
                'pid' => 1488
            )
        )
    ),
    2 => array(
        'hours' => array(
            0 => array(
                0 => '2016/07/04 - 2016/07/10',
                1 => 9.5,
                'pid' => 2
            ),
            1 => array(
                0 => '2016/07/04 - 2016/07/10',
                1 => 8,
                'pid' => 2
            ),
            2 => array(
                0 => '2016/07/04 - 2016/07/10',
                1 => 7,
                'pid' => 2
            ),
            3 => array(
                0 => '2016/07/11 - 2016/07/17',
                1 => 5,
                'pid' => 2
            )
        )
    )
);

// Loop through array...
foreach($data as $pid => $group) {
    foreach($group['hours'] as $row) {
        // I am using the date as a unique key so it's easy to organize
        $new[$pid]['hours'][$row[0]][0] =   $row[0];
        // This will draw an warning if you don't first check that it's set
        if(!isset($new[$pid]['hours'][$row[0]][1]))
            $new[$pid]['hours'][$row[0]][1] =   0;
        // Add values together as you go
        $new[$pid]['hours'][$row[0]][1]     +=  $row[1];
        // On each loop this just assigns the pid (it just keeps overwriting itself
        // but that is no big deal)
        $new[$pid]['hours'][$row[0]]['pid'] =   $pid;
    }
    // Here since you are not using date keys, just reset to numeric
    $new[$pid]['hours'] =   array_values($new[$pid]['hours']);
}

print_r(array_values($new));

Gives you:

Array
(
    [0] => Array
        (
            [hours] => Array
                (
                    [0] => Array
                        (
                            [0] => 2016/07/11 - 2016/07/17
                            [1] => 37
                            [pid] => 1488
                        )

                    [1] => Array
                        (
                            [0] => 2016/07/04 - 2016/07/10
                            [1] => 117
                            [pid] => 1488
                        )

                )

        )

    [1] => Array
        (
            [hours] => Array
                (
                    [0] => Array
                        (
                            [0] => 2016/07/04 - 2016/07/10
                            [1] => 24.5
                            [pid] => 2
                        )

                    [1] => Array
                        (
                            [0] => 2016/07/11 - 2016/07/17
                            [1] => 5
                            [pid] => 2
                        )

                )

        )

)