Reputation: 113
I have this type of associative array.
Array
(
[0] => Array
(
[bookedArea] => Comp Pool
[laneBooked] => 1
[paidBy] => Edmonton Aurora Synchronized Swim Club
[startTime24hr] => 16:00
[finishTime24hr] => 18:00
)
[1] => Array
(
[bookedArea] => Comp Pool
[laneBooked] => 2
[paidBy] => Edmonton Aurora Synchronized Swim Club
[startTime24hr] => 16:00
[finishTime24hr] => 18:00
)
[2] => Array
(
[bookedArea] => Comp Pool
[laneBooked] => 3
[paidBy] => Keyano Swim Club
[startTime24hr] => 16:00
[finishTime24hr] => 18:00
)
)
I would like to make a new array removing similar entries depending on several associations. startTime24hr, finishTime24hr bookedArea & paidBy if all 4 aren't the same then it shouldn't be removed. Plus I would like to capture the first and last lanes in the new associative array.
Array
(
[0] => Array
(
[bookedArea] => Comp Pool
[firstLaneBooked] => 1
[lastLaneBooked] => 2
[paidBy] => Edmonton Aurora Synchronized Swim Club
[startTime24hr] => 16:00
[finishTime24hr] => 18:00
)
[2] => Array
(
[bookedArea] => Comp Pool
[firstLaneBooked] => 3
[lastLaneBooked] => 3
[paidBy] => Keyano Swim Club
[startTime24hr] => 16:00
[finishTime24hr] => 18:00
)
)
I found this which would help me filter with only one association. However I need 3 more.
$copy = $array; // create copy to delete dups from the array you wish to filter from
$newFilteredArray = array(); // new filtered array.
$item1 = 'startTime24hr'; // the association you want to filter with.
for( $i=0; $i<count($array); $i++ ) {
if ( in_array( $array[$i][$item1], $newFilteredArray ) ) {
unset($copy[$i]);
}
else {
$newFilteredArray [] = $array[$i][$item1]
}
}
print_r($copy);
Edit ---- Thank you Alexander for helping me get the iterations correct.
I have been struggling with inserting into my filtered array the start and finish lanes. I have commented out my attempts to make it work. When its uncommented I get: Notice: Undefined index: startTime24hr
and it seems like its in some infinite loop.
But if you comment my stuff no Notices. Can anyone help with this?
function array_push_assoc($array, $key, $value){
$array[$key][] = $value;
return $array;
}
$CPfilteredArray = array();
$lanes = 0;
for($i = 0; $i < count($compPoolArray); $i++) {
$add = true;
// $lanesAdded = false;
// $lanes = $lanes + 1;
// $startLane = $compPoolArray[$i]["laneBooked"];
for($j = 0; $j < count($CPfilteredArray); $j++) {
if(($compPoolArray[$i]["startTime24hr"] === $CPfilteredArray[$j]["startTime24hr"])
&& ($compPoolArray[$i]["finishTime24hr"] === $CPfilteredArray[$j]["finishTime24hr"])
&& ($compPoolArray[$i]["bookedArea"] === $CPfilteredArray[$j]["bookedArea"])
&& ($compPoolArray[$i]["paidBy"] === $CPfilteredArray[$j]["paidBy"])) {
$add = false;
// $lanes = $lanes + 1;
// $lanesAdded = True;
}
}
if($add) {
$CPfilteredArray[] = $compPoolArray[$i];
// if ($lanesAdded){
// $lastLane = $startLane + $lanes;
// $CPfilteredArray[$i] = array_push_assoc($CPfilteredArray, 'firstLane', $startLane);
// $CPfilteredArray[$i] = array_push_assoc($CPfilteredArray, 'lastLane', $lastLane);
// }
// else {
// $CPfilteredArray[$i] = array_push_assoc($CPfilteredArray, 'firstLane', $startLane);
// $CPfilteredArray[$i] = array_push_assoc($CPfilteredArray, 'lastLane', $startLane);
// }
}
}
Upvotes: 1
Views: 196
Reputation: 2893
This may also work: (You can replace the serialize function to only serialize selected elements)
<?php
$arr=array(
0=>array("a"=>1, "b"=>"hello"),
1=>array("a"=>2, "b"=>"hellooo"),
2=>array("a"=>1, "b"=>"hello"),
);
function removeDuplicates( &$arr ){
$index=array();
$result=array();
foreach ($arr as $key=>$val){
$k=serialize($val);
if(!isset($index[$k])){
$index[$k]=$key;
$result[$key]=$val;
}
}
return $result;
}
$result=removeDuplicates($arr);
print_r($arr);
print '<br>';
print_r($result);
?>
Upvotes: 1
Reputation: 2914
If you do know what elements you use to merge array value you may also use a hashmap to do the merge on insertion. So once you add an element to the array you create a hash over
$bookings = array();
$hash = md5($arr['bookedArea'] . $arr['paidBy'] . $arr['startTime24hr'] . $arr['finishTime24hr']);
if ( array_key_exists($hash, $bookings) ){
//add just another lane to the booking
}
else{
//create a new booking entry
}
that way your code may be even more efficient.
Upvotes: 1
Reputation: 758
I know it doesn't really answer (not allowed to comment yet...) your question but if you're retrieving data from db, you could use a query to retrive grouped values. It could look sth like this (pseudo-SQL)
SELECT
bookedArea
,paidBy
,startTime24hr
,finishTime24hr
,MIN(laneBooked)
,MAX(laneBooked)
FROM
reservation -- ??
WHERE
--condition
GROUP BY
bookedArea
,paidBy
,startTime24hr
,finishTime24hr
Upvotes: 1
Reputation: 23537
Two loop cycles do the job.
$filteredArray = array();
for($i = 0; $i < count($array); $i++) {
$add = true;
for($j = 0; $j < count($filteredArray); $j++) {
if(($array[$i]["startTime24hr"] === $filteredArray[$j]["startTime24hr"])
&& ($array[$i]["finishTime24hr"] === $filteredArray[$j]["finishTime24hr"])
&& ($array[$i]["bookedArea"] === $filteredArray[$j]["bookedArea"])
&& ($array[$i]["paidBy"] === $filteredArray[$j]["paidBy"])) {
$add = false;
}
}
if($add) $filteredArray[] = $array[$i];
}
The resulting array called $filteredArray
contains the filtered elements.
Upvotes: 1