PHPのshuffle()が連想配列では使えない件について

↓こんな連想配列があったとして、
$AmericanLeagueEastDivisionTeams = array(
    'BAL' => array('city' => 'Baltimore', 'name' => 'Orioles'),
    'BOS' => array('city' => 'Boston', 'name' => 'Red Sox'),
    'NYY' => array('city' => 'New York', 'name' => 'Yankees'),
    'TB' => array('city' => 'Tampa Bay', 'name' => 'Rays'),
    'TOR' => array('city' => 'Toronto', 'name' => 'Blue Jays'),
);

shuffle()してみると…
shuffle($AmericanLeagueEastDivisionTeams);
var_export($AmericanLeagueEastDivisionTeams);
↓結果(見やすいように整形済み)
array (
  0 => array ('city' => 'Boston', 'name' => 'Red Sox'),
  1 => array ('city' => 'Toronto', 'name' => 'Blue Jays'),
  2 => array ('city' => 'New York', 'name' => 'Yankees'),
  3 => array ('city' => 'Tampa Bay', 'name' => 'Rays'),
  4 => array ('city' => 'Baltimore', 'name' => 'Orioles')
)
はい。キーが破棄されて、数字キーに割り当て直されちゃいます。

じゃあ、array_rand()でランダム順のキーを取得しよう、と思った。
$len = count($AmericanLeagueEastDivisionTeams);
$abbrs = array_rand($AmericanLeagueEastDivisionTeams, $len);
var_export($abbrs);
↓結果
array (
  0 => 'BAL',
  1 => 'BOS',
  2 => 'NYY',
  3 => 'TB',
  4 => 'TOR',
)
よし、この「キーがランダム順に入った配列」を使おう。
…あれ?並べ変わってなくね?
たまたまかな(^o^;

再実行→やっぱりおんなじ→再々実行→やっぱりおんなじ→(無限ループ)
全件取得する場合は並べ換えて紅の豚?
マニュアルに書いといてよ。そんなこと。。

まあ、array_keys()を使ってそれをshuffle()すれば同じ事はできるか。
$abbrs = array_keys($AmericanLeagueEastDivisionTeams);
shuffle($abbrs);
var_export($abbrs);
↓結果
array (
  0 => 'NYY',
  1 => 'BOS',
  2 => 'TB',
  3 => 'BAL',
  4 => 'TOR',
)
当然ながらうまくいく。再実行すればまた並び変わる。

せっかくだから、関数化しておくか。
PHPオリジナルの命名則にあわせて、ashuffle()と名付ける(※)。
オリジナルのshuffle()が並べ替えが成功したかどうかを返しているので、とりあえずtrueを返すことにする。
function ashuffle(&$array) {
    $keys = array_keys($array);
    shuffle($keys);

    $res = array();
    for ($i = 0, $_l = count($keys); $i < $_l; $i++) {
        $res[$keys[$i]] = $array[$keys[$i]];
    }

    $array = $res;
    return true;
}

これで、
ashuffle($AmericanLeagueEastDivisionTeams);

$rank = 0;
foreach ($AmericanLeagueEastDivisionTeams as $abbr => $team) {
    printf("%d: %s %s (%s)¥n", ++$rank, $team['city'], $team['name'], $abbr);
}
↓結果

1: New York Yankees (NYY)
2: Baltimore Orioles (BAL)
3: Tampa Bay Rays (TB)
4: Boston Red Sox (BOS)
5: Toronto Blue Jays (TOR)
成功。


※:蛇足。
この記事を書く時に、そういえば、もうすでに誰かが作ってるよな。"ashuffle()"って名前で。
っと思ってググってみたら、どうやら無いみたい。。
ってことは、このページがひっかかるようになるんだ。ウシシ( ̄ー ̄)

PHP

— posted by たか at 12:12 am   pingTrackBack [0]

T: Y: ALL: Online:
ThemeSwitch
Created in 0.0045 sec.
prev
2011.10
next
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          
 
blogBar
Firefox3 Meter