5

私はこの配列を持っています

$array = array(2, 1, "img1", "img2", "img10", 1.5, "3.14", "2.72");

sort機能を適用した後、

sort($array);

Array
(
    [0] => 2.72
    [1] => 3.14
    [2] => img1
    [3] => img10
    [4] => img2
    [5] => 1
    [6] => 1.5
    [7] => 2
)

並べ替えの方法がわかりませんでした。

誰かが出力配列がどのように達成されるかを説明できますか?

編集:

ここでの問題は、SORT FLAG私が使用すべきものではありませんが、問題は、上記のソートがどのように実行されるかです。ここでは、別のものを使用するようにアドバイスしても意味SORT FLAGがありません。

4

3 に答える 3

6

最初の2つの数字は実際の文字列(引用符で囲んだもの)であるため、次のように扱われます。アルファベット順では、数字は文字の前に配置されます。

他のものは実数(引用符なし)だったので、関数はそれらを別々に置き、数値でソートしました。

array(8)
    0 => '2.72'    [alphabetical]
    1 => '3.14'    [alphabetical]
    2 => 'img1'    [alphabetical]
    3 => 'img10'   [alphabetical]
    4 => 'img2'    [alphabetical]
    5 => 1         [numeric]
    6 => 1.5       [numeric]
    7 => 2         [numeric]

したがって、関数は要素をアルファベット順(a、b、c ...)または数値(1,2,3 ..)のどちらでソートするかを決定する必要があるため、変数タイプをチェックするだけです。

Pekkaが指摘したように、ソートのタイプを強制するために設定できるフラグがあります。それらはドキュメントで説明されています。


編集

この理論はコメントで間違っていることが証明され、私は今完全に失われています(:

ドキュメントのこのコメントには、この問題に関するいくつかの興味深い点が含まれています。

于 2013-02-07T14:32:16.800 に答える
3

Coandaのリンクの情報を出発点として使用すると、PHPが異なる型のオブジェクトを比較するときに型ジャグリングを使用していることは明らかです。問題は、比較中に何が何にキャストされるかを理解することであり、私はまだ完全なリストを見つけることができませんでしたが、一般的には:

intと比較した文字列はになります

(int) string <,>,=, (int) int 

この場合、キャスト後の文字列は0になるため、すべてのintは文字列よりも大きくなります。(期待される)。これは、この種のことについて心配する必要がある唯一のケースです。

PHPはクイックソートを使用し、ほとんどの場合、そのピボットポイントを選択しますarray[n/2]。ここで、nは配列内の要素の数です。これらの2つの情報を知って、上記の配列をクイックソートします。

$pivot = $array[n/2] //n is the number of elements, this sets $pivot='img2'
//compare each element in the list (i am going to this by hand for demonstration)

(int) 'img2' < 2 //int to int comparison;'img2' resolves to 0 and 0 < 2
(int) 'img2' < 1 //int to int comparison;'img2' resolves to 0 and 0 < 1
      'img2' > 'img1' // string to string comparison; strcmp is +256 
      'img2' > 'img 10' //string to string comparison; strcmp is +256 
(float) 'img2' < 1.5 //float to float comparison;'img2' resolves to 0 and 0<1.5 
      'img2' > '3.14' //string to string comparison; strcmp is +54
      'img2' > '2.72' //string to string comparison; strcmp is +55

ここで、2つの新しい配列を作成する必要があります(1つは大きい配列、もう1つは小さい配列)。

 $greater = array('img1', 'img10', '3.14', '2.72);
 $less = array(2, 1, 1.5);

簡単に比較できるすべてのオブジェクトを含む2つの配列を誤って作成したため、これ以上詳しく説明する必要はほとんどありません。$greater文字列しかないので、ここではソートが正常に機能し、すべてが文字列であると見なすことができます。

sort($greater);
var_dump($greater);

を生成します

array(4) {
  [0]=>
  string(5) "2.72"
  [1]=>
  string(4) "3.14"
  [2]=>
  string(4) "img1"
  [3]=>
  string(5) "img10"
}

これは私たちが期待したことであり、上記の結果でもあります。私たちは同じことをします$lesser

$lesser = array(2, 1, 1.5);
sort($lesser);
var_dump($lesser);

我々が得る

array(3) {
  [0]=>
  int(1)
  [1]=>
  float(1.5)
  [2]=>
  int(2)
}

これも期待されています。ここで、3つの配列すべてを連結すると(再帰性のために、「img2」を配列と呼びます)。上記の結果が得られます。

Array
(
[0] => 2.72
[1] => 3.14
[2] => img1
[3] => img10
[4] => img2
[5] => 1
[6] => 1.5
[7] => 2
)

この点を証明するために、この同じ配列に対して同じプロセスに従うことができますが$arr[3]、整数で切り替えます。

$arr = array("img2", 1, "img1", 2, "img10", 1.5, "3.14", "2.72");
sort($arr);
var_dump($arr)

ピボットが文字列からintに変更され、float文字列がfloatとして評価されるため、まったく異なる結果が得られます。

array(8) {
[0]=>
string(4) "img1"
[1]=>
string(5) "img10"
[2]=>
string(4) "img2"
[3]=>
int(1)
[4]=>
float(1.5)
[5]=>
int(2)
[6]=>
string(4) "2.72"
[7]=>
string(4) "3.14"
}
于 2013-02-08T00:53:07.047 に答える
1

次のバグは、混合タイプのソートに関するより多くの洞察を提供します:https ://bugs.php.net/bug.php?id=21728

引用:

<?php
$arr1 = array("a","b","c","d","4",5,4,"true","TRUE",true);
sort($arr1);
var_dump($arr1);
?>

The output is :
array(10) {
  [0]=>
  bool(true)
  [1]=>
  int(4)
  [2]=>
  string(1) "4"
  [3]=>
  string(4) "TRUE"
  [4]=>
  string(1) "a"
  [5]=>
  string(1) "b"
  [6]=>
  string(1) "c"
  [7]=>
  string(1) "d"
  [8]=>
  string(4) "true"
  [9]=>
  int(5)
}

奇妙に見えるかもしれません-なぜ(int)5がすべての文字列の後にあるのですか?これは、「4」が(int)5よりも低く、「4」が「true」の前にあり、「true」が5の前にあるためです。最初の2つは明らかですが、3つ目はそうではありません。しかし、それは大丈夫です。配列内でタイプを混在させない方がよいでしょう。5を「5」に変更すると、「5」は「4」の直後になります。

于 2013-02-07T14:37:14.297 に答える