![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?5a7ff87)
比重(比率)を利用して乱数を取得したいと思って、
そのような関数を探してたのですが見つからなかったので自作したのですが、
関数名の付け方に迷いがあるのでアドバイス頂けないでしょうか?
例えば
array(
array('weight' => 3, 'min' => -3, 'max' => -1),
array('weight' => 7, 'min' => 4, 'max' => 5),
)
と値を渡せば、
30%の確率で-3から-1の間でランダムした結果を取得
70%の確率で4から5の間でランダムした結果を取得
できます。
比重(weight)を利用してるので
「randByWeight」
と仮に名前を付けたのですが、
自分としてはそもそも文法的に合ってるのかも曖昧ですし、
プログラム的な命名規則に則してるかも分かりません・・・
まあそんなに深く考えずに「myrand」とかでもいいんでしょうけど、
この関数の作り方や設計の誤りなども含めてアドバイスして頂きたいです。
/**
* randByWeight
*
* @param $params
* @return int
*/
function randByWeight($params)
{
if (!isset($params[0])) {
$params = array($params);
}
$index = 0;
$range = array();
foreach ($params as $param) {
if ($index >= 1){
$range[$index]['start'] = $range[$index - 1]['end'] + 1;
} else {
$range[$index]['start'] = 1;
}
$range[$index]['end'] = $range[$index]['start'] - 1 + (isset($param['weight']) ? $param['weight'] : 1);
$index++;
}
// srand( (int)( ((float)microtime()) * 1000000 ) );
$ran = rand(1, $range[$index - 1]['end']);
for ($i = 0; $i < $index; $i++) {
if ($range[$i]['start'] <= $ran && $ran <= $range[$i]['end']) {
if (isset($params[$i]['recursive']) && is_array($params[$i]['recursive'])) {
return randByWeight($params[$i]['recursive']);
} else {
if($params[$i]['min'] > $params[$i]['max']) {
$params[$i]['min'] = $params[$i]['max'];
}
return rand($params[$i]['min'], $params[$i]['max']);
}
}
}
}
// 使用例
$arr = array(
array('weight' => 3, 'min' => -10, 'max' => 1),
array(
'weight' => 1,
'recursive' => array(
array('weight' => 1, 'min' => 2, 'max' => 2),
array(
'weight' => 10,
'recursive' => array(
array('weight' => 3, 'min' => 3, 'max' => 3),
array('weight' => 7, 'min' => 4, 'max' => 4),
),
),
),
),
);
$result = array();
for ($i = 1; $i <= 100; $i++) {
$result[randByWeight($arr)]++;
}
$sum = 0;
ksort($result);
foreach ($result as $value => $cnt) {
print "{$value}:{$cnt}<br>\n";
$sum += $cnt;
}
print "sum={$sum}<br>\n";
No.2ベストアンサー
- 回答日時:
#1ですが
引数が全然違ったみたいで失礼しました。
書いてみましたがほとんど同じになってしまいましたw
一応速くはなった気がしますが合ってるかは不明。
少しでも参考になればいいですけど。
class WeightRandomizer {
public static function execute($params) {
if (!isset($params[0])) {
$params = array($params);
}
$weightAll = 0;
foreach($params as $param) {
$weightAll += isset($param['weight']) ? $param['weight'] : 1;
}
$index = rand(1, $weightAll);
$ws = 1;
$we = 1;
foreach($params as $param) {
$we += isset($param['weight']) ? $param['weight'] : 1;
if ($ws <= $index && $index <= $we) {
if (isset($param['recursive']) && is_array($param['recursive'])) {
return self::execute($param['recursive']);
}
if($param['min'] > $param['max']) {
$param['min'] = $param['max'];
}
return rand($param['min'], $param['max']);
}
$ws = $we;
}
}
}
$rand = WeightRandomizer::execute($arr);
ご返答ありがとうございます。
いやでもたしかにこの設計の方が良さそうですね。
なるほど、自分としては
クラスで利用するとインスタンス化する手間が気がかりだったので
考えていなかったのですが、こうやって静的に使えばいいわけですよね。
勘違いしてました・・・
命名の方ですが、
たしかにByWeightなら慣例だと引数はweightですよね・・・
「WeightRandomizer」はいいですね。しっくりきます。
ところで「WeightRandomizer」の「izer(何とかザー)」という語尾は
主にクラスの命名に使うというイメージが自分にはあるのですが、
その認識は間違っているのでしょうか?
それとも一般の関数の命名に適用しても変ではないですか?
No.4
- 回答日時:
一般的にクラス名は名詞、メソッドは動詞を使います。
という慣習からすると Random も一応名詞なので
Random::get() とかでも問題はなさそうです。
-ize で名詞や形容詞を「~化させる・する」の意味の動詞になるので
ランダム化させる+させる人(物)= Randomizer(乱数生成器)
英語は弱い子なので詳しくはお近くのお詳しい方にお願いします。
あえて izer をつけたのはかっこいいからです(キリッ
やっぱりかっこよくコーディングしたいです。
ご返答ありがとうございます。
なるほど、そのような区分けがあれば
名前の付け方も幾分楽になりそうですね。
「izer」はパターンとして使えそうです。
No.1
- 回答日時:
関数の中は見てないですが、命名は問題ないかと。
findById(integer) でIDを条件にレコードを取得だったりしますし。
ByWeightなら 引数はweightとかなと思ったりもしますが。
randByWeight($weight, $min = 0, $max = 1) //PHP的にはこっちかな
randByWeight($weight, $params = array())
クラス化すればまた変わるとは思います。
$rand = new RandomClass();
$rand->setWeight($weight);
print $rand->execute();
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- WordPress(ワードプレス) wordpressでphpを読み込みたい 1 2022/10/30 23:40
- JavaScript 画像の表示位置 3 2022/12/23 08:25
- Visual Basic(VBA) Sheet3から2つの条件でオートフィルターで抽出した個数をSheet2へ入力するマクロで、一つ目の 4 2023/01/12 23:40
- Visual Basic(VBA) 型が一致しませんとエラー 6 2023/07/06 20:14
- Visual Basic(VBA) 別シートから年齢別の件数をカウントしたい 6 2023/01/23 12:00
- JavaScript ソースコードのいじる場所が分かりません。 1 2022/12/23 02:06
- その他(プログラミング・Web制作) pythonのグローバル変数 2 2022/11/25 18:02
- Visual Basic(VBA) ExcelVBAで、index、match関数を使用して、指定範囲に出力したい 3 2022/10/18 21:53
- その他(プログラミング・Web制作) listへのappendが出来ない件 1 2022/12/06 21:44
- Visual Basic(VBA) エクセルのマクロについて教えてください。 2 2023/03/08 09:08
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
php で1から100までの素数の表...
-
C言語 最大値と最小値を求めて...
-
STLのvectorで作った配列をメン...
-
functionの中にfunction?
-
mallocで char *型の配列を確...
-
MYSQLとPHPによって取得する多...
-
PHPのセレクトボックスの初期値...
-
C言語の2次元配列における行・...
-
C言語の配列をPush(追加)する...
-
配列の比較
-
多次元連想配列 検索 削除 ...
-
配列の要素をキーにする
-
templateを使ったXOR swapのバ...
-
プログラミングのPythonのnoteb...
-
フォームのデータを受け取りに...
-
配列について
-
共通項を持つ配列同士を結合さ...
-
配列 一部除外してソート?
-
arrayをどうやって表示するのか?
-
連想配列で値が空だったら、要...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
プログラミングのPythonのnoteb...
-
スカラーのベクトル微分
-
特定の文からメールアドレスの...
-
CArrayの要素としてCStringArra...
-
C言語 最大値と最小値を求めて...
-
行列
-
読み(あ行~わ行)ごとに分け...
-
配列の要素(value)に、変数を...
-
C言語の配列をPush(追加)する...
-
STLのvectorで作った配列をメン...
-
php で1から100までの素数の表...
-
【PHP】配列のキー名の修正は可...
-
Perlで重複行を削除したい
-
fgetc関数について
-
CArrayのソート
-
ファイルの書き込みについて教...
-
配列の添え字が小数だとどうなる?
-
PHPのmin関数、「1」以上の数値...
-
forとかで連番の変数を一気に格...
-
delphi 2次元配列がわかりません
おすすめ情報