【问题标题】:How to sort array by month abbreviation如何按月份缩写对数组进行排序
【发布时间】:2021-12-29 18:33:52
【问题描述】:

我有一个多维数组,我正在尝试按 3 个字母的月份缩写进行排序,这是我尝试过的:

数组: $shipping_chart_month =

[
  {
    "name": "8:00 AM",
    "data": [
        {
          "x": "May",
          "y": 37
        },
        {
          "x": "Nov",
          "y": 32
        },
        {
          "x": "Apr",
          "y": 1
        },
        {
          "x": "Aug",
          "y": 45
        },
        {
          "x": "Sep",
          "y": 19
        },
        {
          "x": "Jul",
          "y": 13
        },
        {
          "x": "Oct",
          "y": 43
        },
        {
          "x": "Jun",
          "y": 31
        },
        {
          "x": "Feb",
          "y": 0
        },
        {
          "x": "Jan",
          "y": 0
        },
        {
          "x": "Mar",
          "y": 0
        }
      ]
    },
    {
      "name": "9:00 AM",
      "data": [
        {
          "x": "Apr",
          "y": 26
        },
        {
          "x": "Oct",
          "y": 84
        },
        {
          "x": "Sep",
          "y": 35
        },
        {
          "x": "Jul",
          "y": 26
        },
        {
          "x": "Feb",
          "y": 6
        },
        {
          "x": "Nov",
          "y": 96
        },
        {
          "x": "Mar",
          "y": 10
        },
        {
          "x": "May",
          "y": 50
        },
        {
          "x": "Aug",
          "y": 66
        },
        {
          "x": "Jun",
          "y": 36
        },
        {
          "x": "Jan",
          "y": 0
        }
      ]
    }
]

我正在尝试按月对每个子 data 数组进行排序。这是我尝试过的,但它似乎没有任何影响,并且停留在从这里去哪里:

 foreach ($shipping_chart_month as $data) {
     $months = [];
     foreach ($data['data'] as $month) {
         $months[] = $month['x'];
     }
     usort($months, function ($x, $y) {
         $months = array('Jan' => 1, 'Feb' => 2, 'Mar' => 3, 'Apr' => 4, 'May' => 5, 'Jun' => 6, 'Jul' => 7, 'Aug' => 8, 'Sep' => 9, 'Oct' => 10, 'Nov' => 11, 'Dec' => 12);
         if ($months[$x] == $months[$y]) {
             return 0;
         }
         return ($months[$x] > $months[$y]) ? 1 : -1;
     });
 }

【问题讨论】:

  • 这个问题看起来与your previous one 非常相似。你从那里的答案中学到了什么?
  • @KIKOSoftware 将一些缺失值添加到数组中,我不想事后在一篇文章中提出多个单独的问题。但是,是的,我尝试了许多 usort 函数,但似乎无法获得它
  • 那不是一个有效的 php 数组。
  • 另外:你期待什么?您的代码只会在新数组中收集月份别名。
  • @cottton 抱歉,我刚刚从我的 IDE 中复制了返回的输出。但是,是的,我想我不完全理解 usort 如何将新排序的值添加回原始数组。

标签: php arrays usort


【解决方案1】:

你很亲密。
月份别名图(Jan => 1, ...)是个好主意。
您只需要遍历主数组中的所有数组
并对它们进行排序(通过引用)。

注意:我使用uasort,但你也可以使用usort

源数组:

$shipping_chart_month = [
    [
        "name" => "8=>00 AM",
        "data" => [
            [
                "x" => "May",
                "y" => 37
            ],
            [
                "x" => "Nov",
                "y" => 32
            ],
            [
                "x" => "Apr",
                "y" => 1
            ],
            [
                "x" => "Aug",
                "y" => 45
            ],
            [
                "x" => "Sep",
                "y" => 19
            ],
            [
                "x" => "Jul",
                "y" => 13
            ],
            [
                "x" => "Oct",
                "y" => 43
            ],
            [
                "x" => "Jun",
                "y" => 31
            ],
            [
                "x" => "Feb",
                "y" => 0
            ],
            [
                "x" => "Jan",
                "y" => 0
            ],
            [
                "x" => "Mar",
                "y" => 0
            ]
        ]
    ],
    [
        "name" => "9=>00 AM",
        "data" => [
            [
                "x" => "Apr",
                "y" => 26
            ],
            [
                "x" => "Oct",
                "y" => 84
            ],
            [
                "x" => "Sep",
                "y" => 35
            ],
            [
                "x" => "Jul",
                "y" => 26
            ],
            [
                "x" => "Feb",
                "y" => 6
            ],
            [
                "x" => "Nov",
                "y" => 96
            ],
            [
                "x" => "Mar",
                "y" => 10
            ],
            [
                "x" => "May",
                "y" => 50
            ],
            [
                "x" => "Aug",
                "y" => 66
            ],
            [
                "x" => "Jun",
                "y" => 36
            ],
            [
                "x" => "Jan",
                "y" => 0
            ]
        ]
    ]
];

排序:

// The month alias map.
$monthAliasMap = array(
    // {month alias} => {sort priority (lower before higher)}
    'Jan' => 1,
    'Feb' => 2,
    'Mar' => 3,
    'Apr' => 4,
    'May' => 5,
    'Jun' => 6,
    'Jul' => 7,
    'Aug' => 8,
    'Sep' => 9,
    'Oct' => 10,
    'Nov' => 11,
    'Dec' => 12,
);
// Note: using each $array in $shipping_chart_month by reference.
foreach ($shipping_chart_month as &$array) {
    uasort($array['data'], function ($a, $b) use ($monthAliasMap) {
        // $a | $b example:
        // array (
        //     'x' => 'May',
        //     'y' => 37,
        // )

        // Set the offset we expect the month alias on.
        $offset = 'x';
        // Get the month alias from a and b.
        $aMonthAlias = $a[$offset]; // F.e. "Jan" or "Dec" ...
        $bMonthAlias = $b[$offset]; // F.e. "Jan" or "Dec" ...
        // Get (map) the sort priority for a and b.
        $aPriority = (int)$monthAliasMap[$aMonthAlias]; // F.e. 1 or 2 ...
        $bPriority = (int)$monthAliasMap[$bMonthAlias]; // F.e. 1 or 2 ...

        // Sort them.
        if ($aPriority === $bPriority) {
            return 0;
        }
        // a < b === asc ; a > b === desc
        return ($aPriority < $bPriority) ? -1 : 1;
    });

}
unset($array); // Release reference.

结果(缩短):

[
    0 => [
        'name' => '8=>00 AM',
        'data' => [
            9 => [
                'x' => 'Jan',
                'y' => 0,
            ],
            8 => [
                'x' => 'Feb',
                'y' => 0,
            ],
            // ...
            1 => [
                'x' => 'Nov',
                'y' => 32,
            ],
        ],
    ],
    1 => [
        'name' => '9=>00 AM',
        'data' => [
            10 => [
                'x' => 'Jan',
                'y' => 0,
            ],
            4  => [
                'x' => 'Feb',
                'y' => 6,
            ],
            // ...
            5  => [
                'x' => 'Nov',
                'y' => 96,
            ],
        ],
    ],
];

【讨论】:

    【解决方案2】:

    从 JSON 字符串中的数据开始,这就是您在上面介绍的内容:

    $shipping = '[
      {
          "name": "8:00 AM",
        "data": [
            {
                "x": "May",
              "y": 37
            },
            {
                "x": "Nov",
              "y": 32
            },
            {
                "x": "Apr",
              "y": 1
            },
            {
                "x": "Aug",
              "y": 45
            },
            {
                "x": "Sep",
              "y": 19
            },
            {
                "x": "Jul",
              "y": 13
            },
            {
                "x": "Oct",
              "y": 43
            },
            {
                "x": "Jun",
              "y": 31
            },
            {
                "x": "Feb",
              "y": 0
            },
            {
                "x": "Jan",
              "y": 0
            },
            {
                "x": "Mar",
              "y": 0
            }
          ]
        },
        {
            "name": "9:00 AM",
          "data": [
            {
                "x": "Apr",
              "y": 26
            },
            {
                "x": "Oct",
              "y": 84
            },
            {
                "x": "Sep",
              "y": 35
            },
            {
                "x": "Jul",
              "y": 26
            },
            {
                "x": "Feb",
              "y": 6
            },
            {
                "x": "Nov",
              "y": 96
            },
            {
                "x": "Mar",
              "y": 10
            },
            {
                "x": "May",
              "y": 50
            },
            {
                "x": "Aug",
              "y": 66
            },
            {
                "x": "Jun",
              "y": 36
            },
            {
                "x": "Jan",
              "y": 0
            }
          ]
        }
    ]';
    
    // json_decode() the data so we can work with it.
    $shipping_chart_month = json_decode($shipping);
    
    
    // Loop through the array of objects, looking at the $data property in each one
    foreach($shipping_chart_month as $chart) {
    
        // usort() sorts in place, so apply it to the $data array
        usort($chart->data, function($a, $b){
            $months = array('Jan' => 1, 'Feb' => 2, 'Mar' => 3, 'Apr' => 4, 'May' => 5, 'Jun' => 6, 'Jul' => 7, 'Aug' => 8, 'Sep' => 9, 'Oct' => 10, 'Nov' => 11, 'Dec' => 12);
            // We use the $months array to swap from a month abbreviation to a 
            // numeric value.
            // We compare the index of the x property of the objects in the $data array
            // the spaceship operator compares and returns -1, 0, 1 as appropriate 
            return $months[$a->x]<=>$months[$b->x];
        });
    }
    
    // Output the results.
    print_r($shipping_chart_month);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-04
      • 2018-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多