🐘

GoにPHPのsort()を移植した

2024/05/13に公開

先日 PHPのsort関数について調べた のですが、その一環でPHPのsort関数をGoに移植してみました。

使い方

こんな感じに使うと SORT_REGULAR でソートされます。

package main

import (
    "fmt"

    "github.com/demouth/phpsort-go/v2"
)

func main() {
    // PHP8
    strings := []string{
        "1.0",
        " 1",
        "1 ",
        "+1.0",
    }
    phpsort.Sort(strings)
    fmt.Printf("%#v\n", strings) // []string{"1.0", " 1", "1 ", "+1.0"}
}

上記に対応するPHP8のコードは次のとおりです。

<?php
$a = [
  '1.0',
  ' 1',
  '1 ',
  '+1.0',
];
sort($a);
var_dump($a);
/*
PHP 8.3.2 (cli) (built: Feb 13 2024 05:36:23) (NTS)
array(4) {
  [0]=>
  string(3) "1.0"
  [1]=>
  string(2) " 1"
  [2]=>
  string(2) "1 "
  [3]=>
  string(4) "+1.0"
}
*/

PHP7について

PHPはメジャーバージョンごとにソートロジックに変更が入っているため、PHP7とPHP8でソート結果が異なるケースがあります(詳しくはこちらの記事を参照)。phpsort-go はデフォルトではPHP8の仕様でソートを行いますが、次のようにオプションを渡すとPHP7の仕様でソートします。

package main

import (
    "fmt"

    "github.com/demouth/phpsort-go/v2"
)

func main() {
    // PHP7
    strings := []string{
        "1.0",
        " 1",
        "1 ",
        "+1.0",
    }
    phpsort.Sort(strings, phpsort.WithPHP7Mode())
    fmt.Printf("%#v\n", strings) // []string{"1.0", " 1", "+1.0", "1 "}
}

同じコードをPHP7で実行すると次のとおりで、 phpsort-go と同じ結果になることが分かります。

<?php
$a = [
  '1.0',
  ' 1',
  '1 ',
  '+1.0',
];
sort($a);
var_dump($a);
/*
PHP 7.4.33 (cli) (built: Nov 15 2022 06:01:17) ( NTS )
array(4) {
  [0]=>
  string(3) "1.0"
  [1]=>
  string(2) " 1"
  [2]=>
  string(4) "+1.0"
  [3]=>
  string(2) "1 "
}
*/

注意点

PHPの仕様を再現するためのロジックが入っているので sort.SliceStable などの標準packageと比べると少し遅いので注意が必要です。

以上です。
非常にマニアックなpackageなので必要とする人は少ない気がしますが、使えれば使ってみて下さい。

Discussion