【问题标题】:Using PHP to loop JSON and generate a new format of nested JSON使用PHP循环JSON并生成嵌套JSON的新格式
【发布时间】:2017-05-05 10:08:25
【问题描述】:

在 PHP 中,如何循环遍历以下 JSON 对象的日期键,如果日期值相同则合并时间:

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

结果应该是这样的:

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

我是否应该创建一个空数组,然后循环遍历 JSON 并重新创建一个新的 JSON?有没有更好的方法或者解决方案可以参考?

谢谢!

【问题讨论】:

  • 我认为时间将是一个数组,而不是一个包含格式不正确的对象的数组。我建议你先阅读 json 手册。我猜你应该有这样的输出: [ { date: "27-06-2017", time: ["1430", "1500"] } ]
  • 感谢您指出,这很有意义。
  • 如果你有大数据,你可以检查 if else 条件和一些 find 功能,或者你可以用简单的方法来检查两列

标签: php arrays json key


【解决方案1】:

这个解决方案有点开销,但是如果你确定你的数据是顺序和排序的,你可以使用array_count_valuesarray_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);

这里是working demo

【讨论】:

  • 这个看起来不错!通过添加 echo json_encode($grouped);我可以得到我正在寻找的结果。让我在 2 天内测试一下,以比较与 foreach 的速度。谢谢!!
【解决方案2】:

这样做的另一个想法是

<?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);
?>

现场演示:https://eval.in/787695

【讨论】:

  • 在经历了几个解决方案之后,我发现这个更容易理解并且只使用了 1 个 for 循环。非常感谢大家的回答!!!
  • 抱歉,我喜欢这个答案,但格式与我所要求的略有不同。
【解决方案3】:

请试试这个:

$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]; 
}

【讨论】:

  • 这不是解决方案
  • 答案很好,但有没有办法像@Marius Bogdan 建议的那样拥有键值对? [{日期:“27-06-2017”,时间:[“1430”,“1500”]}]
  • 感谢您的快速回答,认为第二个 foreach 中的 $op[] 是 $op2[]。所以我必须使用 2 foreach 循环?如果数据量很大,可能效率不高吧?
  • 第二个foreach应该是: foreach($op as $key => $val){ $op2[] = ['date' => $key, 'time' => $val]; }
【解决方案4】:
// 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);

"final" 数组最初是使用基于日期的索引创建的,因此您可以确定它们是否已设置,以便您操作正确的 "time" em> 数组。

它们只是通过将$final 放入array_values() 来删除,以获得您所追求的零索引数组。

json_encode($final) 会给你想要的 JSON:

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

【讨论】:

    【解决方案5】:

    另一种解决方案:

    $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));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-12
      • 2021-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-17
      • 1970-01-01
      相关资源
      最近更新 更多