【问题标题】:Algorithm for removing duplicates from Json Array从 Json 数组中删除重复项的算法
【发布时间】:2017-06-09 21:25:27
【问题描述】:

我有这个 JSON 数据:

[{"make":"Cadillac","model":"Escalade","year":"2006"},{"make":"Cadillac","model":"Escalade","year":"2005"},{"make":"Cadillac","model":"Escalade","year":"2004"},{"make":"Cadillac","model":"Escalade","year":"2003"},{"make":"Cadillac","model":"Escalade","year":"2002"},{"make":"Cadillac","model":"Escalade ESV","year":"2006"},{"make":"Cadillac","model":"Escalade ESV","year":"2005"},{"make":"Cadillac","model":"Escalade ESV","year":"2004"},{"make":"Cadillac","model":"Escalade ESV","year":"2003"},{"make":"Cadillac","model":"Escalade EXT","year":"2006"},{"make":"Cadillac","model":"Escalade EXT","year":"2005"},{"make":"Cadillac","model":"Escalade EXT","year":"2004"},{"make":"Cadillac","model":"Escalade EXT","year":"2003"},{"make":"Cadillac","model":"Escalade EXT","year":"2002"},{"make":"Chevrolet","model":"Astro","year":"2005"},{"make":"Chevrolet","model":"Astro","year":"2004"},{"make":"Chevrolet","model":"Astro","year":"2003"},{"make":"Chevrolet","model":"Avalanche 1500","year":"2006"},{"make":"Chevrolet","model":"Avalanche 1500","year":"2005"}]

如何对数据格式进行排序。

Cadillac    Escalade    07-13
Cadillac    Escalade ESV    07-13
Cadillac    Escalade EXT    07-13
Cadillac    XTS 2013
Chevrolet   Avalanche   07-13
Chevrolet   Express 1500    09-14

我对 PHP 还很陌生,所以我很难弄清楚如何实现这一点并删除重复项以及通过串联添加年份。

谢谢,

【问题讨论】:

  • 什么是07-13?它不会出现在您的 json 数据中
  • 通过串联添加年份。

标签: php arrays json sorting search


【解决方案1】:
$data = json_decode('[{"make":"Cadillac","model":"Escalade","year":"2006"},{"make":"Cadillac","model":"Escalade","year":"2005"},{"make":"Cadillac","model":"Escalade","year":"2004"},{"make":"Cadillac","model":"Escalade","year":"2003"},{"make":"Cadillac","model":"Escalade","year":"2002"},{"make":"Cadillac","model":"Escalade ESV","year":"2006"},{"make":"Cadillac","model":"Escalade ESV","year":"2005"},{"make":"Cadillac","model":"Escalade ESV","year":"2004"},{"make":"Cadillac","model":"Escalade ESV","year":"2003"},{"make":"Cadillac","model":"Escalade EXT","year":"2006"},{"make":"Cadillac","model":"Escalade EXT","year":"2005"},{"make":"Cadillac","model":"Escalade EXT","year":"2004"},{"make":"Cadillac","model":"Escalade EXT","year":"2003"},{"make":"Cadillac","model":"Escalade EXT","year":"2002"},{"make":"Chevrolet","model":"Astro","year":"2005"},{"make":"Chevrolet","model":"Astro","year":"2004"},{"make":"Chevrolet","model":"Astro","year":"2003"},{"make":"Chevrolet","model":"Avalanche 1500","year":"2006"},{"make":"Chevrolet","model":"Avalanche 1500","year":"2005"}]');

// Organize by make and model
foreach ($data as $row) {
  $organized[$row->make][$row->model][] = $row->year;
}

// Output.
foreach ($organized as $make => $models) {
  foreach ($models as $model => $years) {
    sort($years);
    // Use first value as range.
    $range = array_shift($years);
    // If there are more years, create a range.
    if (count($years)) {
      // Use last value as end of range.
      $range .= '-' . array_pop($years);
    }
    // Print formatted line with tabs.
    echo $make, "\t", $model, "\t", $range, "\n";
  }
}

输出:

Cadillac    Escalade    2002-2006
Cadillac    Escalade ESV    2003-2006
Cadillac    Escalade EXT    2002-2006
Chevrolet   Astro   2003-2005
Chevrolet   Avalanche 1500  2005-2006

$organized,在第一个foreach中创建,是一个多维数组,如下所示:

Array
(
    [Cadillac] => Array
        (
            [Escalade] => Array
                (
                    [0] => 2006
                    [1] => 2005
                    [2] => 2004
                    [3] => 2003
                    [4] => 2002
                )

            [Escalade ESV] => Array
                (
                    [0] => 2006
                    [1] => 2005
                    [2] => 2004
                    [3] => 2003
                )

            [Escalade EXT] => Array
                (
                    [0] => 2006
                    [1] => 2005
                    [2] => 2004
                    [3] => 2003
                    [4] => 2002
                )

        )

    [Chevrolet] => Array
        (
            [Astro] => Array
                (
                    [0] => 2005
                    [1] => 2004
                    [2] => 2003
                )

            [Avalanche 1500] => Array
                (
                    [0] => 2006
                    [1] => 2005
                )

        )

)

【讨论】:

  • 这很优雅我已经尝试了 2 天,你能用 if 语句而不是三元运算来重构吗?也许还可以解释两个 foreach 循环和排序发生了什么?一些额外的 cmets 只是这样我才能真正抓住这背后的逻辑。干得好,虽然这正是我想要完成的。
  • @hayonj,我添加了更多细节。
  • 我不明白 `if (count($years))` 我会在上面使用 for 循环,你能解释一下它的作用吗?
  • 从我添加到答案中的数组转储中可以看出,$years 变成了 JSON 数据中所有可用年份的数组。我对count($years) 所做的是检查是否有更多值以创建年份范围。 array_shift 从数组中删除第一项。如果 count 返回任何值,我知道我需要创建一个年份范围。
  • 你在重构之前的第一段代码是这样的:$sorted = array_map(function ($arr) { return array_map(function ($a) { sort($a); return $a; }, $arr); }, $organized);你能解释一下array_map和匿名函数发生了什么吗?谢谢。
【解决方案2】:

你必须用一个循环来解析它。一个简单的版本如下所示:

$cars = json_decode($cars_json);
$carList = array();
foreach($cars as $car){
    if(!isset($carList[$car->make . $car->model])){
        $carList[$car->make . $car->model] = array(
            'firstYear' => $car->year,
            'lastYear' => $car->year,
            'make'=>$car->make,
            'model' => $car->model,
    }
    else{
        if($car->year < $carList[$car->make . $car->model]['firstYear'])
            $carList[$car->make . $car->model]['firstYear'] = $car->year;
        else if($car->year > $carList[$car->make . $car->model]['lastYear'])
            $carList[$car->make . $car->model]['lastYear'] = $car->year;
    }
}
//Parsing complete, now output

foreach($carList as $car){
  echo $car['make'] . " ";
  echo $car['model'] . " ";
  echo substr($car['firstYear'],-2) . "-" . substr($car['lastYear'], -2);
}

【讨论】:

    猜你喜欢
    • 2016-01-05
    • 2016-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-09
    • 2011-06-29
    • 2011-01-04
    相关资源
    最近更新 更多