0

In PHP, how do I loop through the following JSON Object's date key, if the date value are the same then merge the time:

[
  {
    date: "27-06-2017",
    time: "1430"
  },
  {
    date: "27-06-2017",
    time: "1500"
  },
  {
    date: "28-06-2017",
    time: "0930"
  },
  {
    date: "28-06-2017",
    time: "0915"
  }
] 

Result should looks like this:

[
  {
    date: "27-06-2017",
    time: [{"1430","1500"}]
  },      {
    date: "28-06-2017",
    time: [{"0930, 0915"}]
  }
] 

Should I create an empty array, then the looping through the JSON and recreate a new JSON? Is there any better way or any solution to reference?

Thank you!

3
  • 1
    I think time will be an array, not an array with an object which is not well formated. I would suggest you to read the json manual first. I guess you should have an output like this: [ { date: "27-06-2017", time: ["1430", "1500"] } ] Commented May 5, 2017 at 10:11
  • Thanks for pointing that, it make senses. Commented May 5, 2017 at 10:14
  • you can check with if else condition and some find function if you have large data or you can do it simple way like check two column Commented May 5, 2017 at 10:20

5 Answers 5

1

This solution is a little overhead, but if you are sure that your data is sequential and sorted, you can use array_count_values and array_map:

$count = array_count_values(array_column($array, 'date'));
$times = array_column($array, 'time');
$grouped = array_map(function ($date, $count) use (&$times) {
    return [
        'date' => $date,
        'time' => array_splice($times, 0, $count)
    ];    
}, array_keys($count), $count);

Here is working demo.

Sign up to request clarification or add additional context in comments.

1 Comment

This one looks good! By adding echo json_encode($grouped); I could get the result I am looking for. Let me test it out in 2 days to compare the speed with foreach. Thanks!!
1

Another Idea to do this is

<?php
    $string = '[{"date": "27-06-2017","time": "1430"},{"date": "27-06-2017","time": "1500"},{"date": "28-06-2017","time": "0930"},{"date": "28-06-2017","time": "0915"}]';
    $arrs = json_decode($string);
    $main = array();
    $temp = array();
    foreach($arrs as $arr){
      if(in_array($arr->date,$temp)){
        $main[$arr->date]['time'][] = $arr->time;
      }else{
        $main[$arr->date]['date'] = $arr->date;
        $main[$arr->date]['time'][] = $arr->time;
        $temp[] = $arr->date;
      }
    }
    echo json_encode($main);
?>

live demo : https://eval.in/787695

2 Comments

After gone through the few solutions, i found this one easier to be understand and using only 1 for loop. Thank you so much everyone for the answers!!!
Sorry, I like the answer but the format is slightly different than what I was asking.
1

Please try this:

$a = [] // Your input array
$op= [];//output array
foreach($a as $key => $val){
    $key = $val['date'];
    $op[$key][] = $val['time'];
}
$op2 = [];
foreach($op as $key => $val){
    $op2[] = ['date' => $key, 'time' => $val]; 
}

4 Comments

this is not solution
The answer is good but is there a way to have key value pair like @Marius Bogdan suggested? [ { date: "27-06-2017", time: ["1430", "1500"] } ]
Thanks for your quick answer, think the $op[] in 2nd foreach is $op2[]. so I have to use 2 foreach loop? if data size is big, it might be not that efficient right?
The 2nd foreach should be: foreach($op as $key => $val){ $op2[] = ['date' => $key, 'time' => $val]; }
1
// create the "final" array
$final = [];

// loop the JSON (assigned to $l)
foreach($l as $o) {

    // assign $final[{date}] = to be a new object if it doesn't already exist
    if(empty($final[$o->date])) {
        $final[$o->date] = (object) ['date' => $o->date, 'time' => [$o->time]];
    }

    // ... otherwise, if it does exist, just append this time to the array
    else {
        $final[$o->date]->time[] = $o->time;
    }
}

// to get you back to a zero-indexed array
$final = array_values($final);

The "final" array is created with date based indexes initially so that you can determine whether they've been set or not to allow you to manipulate the correct "time" arrays.

They're just removed at the end by dropping $final into array_values() to get the zero-indexed array you're after.

json_encode($final) will give you want you want as a JSON:

[{"date":"27-06-2017","time":["1430","1500"]},{"date":"28-06-2017","time":["0930","0915"]}]

Comments

1

Yet another solution :

$d = [];
$dizi = array_map(function ($value) use (&$d) {
    if (array_key_exists($value->date, $d)) {
        array_push($d[$value->date]['time'], $value->time);
    } else {
        $d[$value->date] = [
            'date' => $value->date,
            'time' => [$value->time]
        ];
    }
}, $array);
echo json_encode(array_values($d));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.