0

アルファベット順の配列のソートが正しく出力されません。

次のように出力されました。

デモ qwerty Demo3 Test1 Test2 New1

それ以外の:

デモ デモ3 New1 qwerty Test1 Test2

コード:

<?php

$dbresults= array ( "0"  => array ( "id" => "1",
                              "cb_boutiquename1" => "Test1",
                              "cb_boutiquename2" => "Test2",
                              "cb_boutiquename3" => "New1"
                                 ),
              "1" => array ( "id" => "2",
                              "cb_boutiquename1" => "Demo",
                              "cb_boutiquename2" => "qwerty",
                              "cb_boutiquename3" => "Demo3"
                                 )
            );

    function sortarray($a, $b) {
        return strcmp($a["cb_boutiquename$i"], $b["cb_boutiquename$i"]);
    }

    usort($dbresults, "sortarray");

    while (list($key, $value) = each($dbresults)) {
        $results[] = $value ;
    }

    foreach($results as $result) {
        $i = 1;
        while (array_key_exists("cb_boutiquename$i", $result)) {
        if ($result["cb_boutiquename$i"] !='') {
            echo '<a href=' . cbSef( 'index.php?option=com_comprofiler&task=page&user=' . (int) $result['id'] . '&b=' . $i . getCBprofileItemid( false )) . '>' . $result["cb_boutiquename$i"] . '</a><br />';
        }
        ++$i;
        }
    }
?>
4

2 に答える 2

1

あなたの問題は、ここにあるということです:

function sortarray($a, $b) {
    return strcmp($a["cb_boutiquename$i"], $b["cb_boutiquename$i"]);
}

$i は未定義なので、基本的に未定義の配列オフセットを別の配列オフセットと比較しています。

実行時にどの cb_boutiquename フィールドを指定するかを指定したい場合は、関数に $i を含めることをお勧めします。PHP では、クロージャーを返す関数を使用してこれを行うことができます (PHP 5.3 以降)。

function getSorter($idx){
       return function($a, $b) use ($idx) {
           return strcmp($a["cb_boutiquename$idx"], $b["cb_boutiquename$idx"]);
       };
}

これは、指定された引数を閉じる関数を返し、usort の比較関数として使用するのに適しています。したがって、並べ替え呼び出しには次を使用します。

usort($dbresults, getSorter(1));

または、プロパティの cb_boutiquename プレフィックスを想定しないより一般的なソリューションの場合、これを次のように変更できます。

function getSorter($idx){
       return function($a, $b) use ($idx) {
           return strcmp($a[$idx], $b[$idx]);
       };
}
usort($dbresults, getSorter("cb_boutiquename1"));

これにより、配列の配列をいずれかのインデックスでソートできます。

更新 この演習の目的を完全に誤解していました。やりたいことは、並べ替えを行う前に配列をフラットにすることです。

    $dbresults= array ( "0"  => array ( "id" => "1",
                          "cb_boutiquename1" => "Test1",
                          "cb_boutiquename2" => "Test2",
                          "cb_boutiquename3" => "New1"
                             ),
          "1" => array ( "id" => "2",
                          "cb_boutiquename1" => "Demo",
                          "cb_boutiquename2" => "qwerty",
                          "cb_boutiquename3" => "Demo3"
                             )
        );

// flatten out the array
$results = array();
foreach($dbresults as $k=>$v){
    foreach ($v as $key=>$value) {
          if (substr($key, 0,15) == "cb_boutiquename"){
              $results[] = array("id"=>$v["id"], "cb_boutiquename"=>$value, "i"=>substr($key, 15));
          }
    }

}

usort($results, function($a, $b){ return strcasecmp($a["cb_boutiquename"], $b["cb_boutiquename"]); });
foreach($results as $result){
    echo '<a href=' . cbSef( 'index.php?option=com_comprofiler&task=page&user=' . (int) $result['id'] . '&b=' . $result["i"] . getCBprofileItemid( false )). '>' . $result["cb_boutiquename"] . '</a><br />'."\n";
}
于 2013-08-22T14:22:07.067 に答える
0

あなたの関数の代わりに、sortarray単にこれを使用してください:

asort($dbresults);

車輪を再発明する必要はありません。ここでそれについて読んでください

于 2013-08-22T14:12:04.260 に答える