วิธีรับค่าสุ่มจากอาร์เรย์


124

ฉันมีอาร์เรย์ที่เรียกว่า $ran = array(1,2,3,4);

ฉันต้องการรับค่าสุ่มจากอาร์เรย์นี้และเก็บไว้ในตัวแปรฉันจะทำสิ่งนี้ได้อย่างไร

คำตอบ:


232

คุณยังสามารถทำได้เพียง:

$k = array_rand($array);
$v = $array[$k];

นี่คือวิธีที่ต้องทำเมื่อคุณมีอาร์เรย์เชื่อมโยง


11
ตามความคิดเห็น array_randนี้ไม่สุ่มเท่าที่ควร
Timo Huovinen

1
หรือคุณสามารถต้องการแพ็คเกจนี้และใช้งานได้array_rand_value
ปิด

10
ตั้งแต่ PHP 7.1 array_rand()ใช้ Mersenne Twister กำเนิด: แรนด์ () นามแฝง mt_rand () และ srand () นามแฝง mt_srand () ในทางปฏิบัติตอนนี้ควรจะดีพอแล้ว
Gras Double

32

PHP มีฟังก์ชันสำหรับสิ่งนั้น: array_rand ()
http://php.net/manual/en/function.array-rand.php

$ran = array(1,2,3,4);
$randomElement = $ran[array_rand($ran, 1)];

3
ค่าเริ่มต้นของอาร์กิวเมนต์ที่สองของarray_randฟังก์ชัน1จึงไม่จำเป็นต้องเขียน
Nabi KAZ

23

คุณสามารถใช้mt_rand ()

$random = $ran[mt_rand(0, count($ran) - 1)];

สิ่งนี้มีประโยชน์ในฐานะฟังก์ชันเช่นกันหากคุณต้องการค่า

function random_value($array, $default=null)
{
    $k = mt_rand(0, count($array) - 1);
    return isset($array[$k])? $array[$k]: $default;
}

4
ควรเป็น mt_rand (0, 3) เนื่องจากมีเพียง 4 รายการเท่านั้น อย่างถูกต้องมากขึ้นแม้ว่า: $ array [mt_rand (0, count ($ array)]
reko_t

2
เอ่อฉันคิดว่าคุณหมายถึง mt_rand (0, count ($ ran) - 1)
Josh Davis

ตามความคิดเห็นของ php array_randไม่สุ่มเท่าที่ควรดังนั้นจึงmt_randเป็นที่ต้องการ
Timo Huovinen

1
ประเด็นทั้งหมดในissetส่วนนี้คืออะไร? สิ่งนี้จะล้มเหลวสำหรับอาร์เรย์ที่เชื่อมโยงอยู่ดี
Luke Cousins

ฉันไม่รู้ว่าทำไม แต่เมื่อใช้mt_randแทนrandในกรณีนี้ดูเหมือนว่าจะชอบบางรายการมากกว่ารายการอื่น
user151496


14

คุณสามารถใช้ฟังก์ชัน array_rand เพื่อเลือกคีย์สุ่มจากอาร์เรย์ของคุณดังด้านล่าง

$array = array("one", "two", "three", "four", "five", "six");
echo $array[array_rand($array, 1)];

หรือคุณสามารถใช้ฟังก์ชัน Rand and count เพื่อเลือกดัชนีแบบสุ่ม

$array = array("one", "two", "three", "four", "five", "six");
echo $array[rand(0, count($array) - 1)];

11

มาจาก Laravel Collection::random():

function array_random($array, $amount = 1)
{
    $keys = array_rand($array, $amount);

    if ($amount == 1) {
        return $array[$keys];
    }

    $results = [];
    foreach ($keys as $key) {
        $results[] = $array[$key];
    }

    return $results;
}

การใช้งาน:

$items = ['foo', 'bar', 'baz', 'lorem'=>'ipsum'];

array_random($items); // 'bar'
array_random($items, 2); // ['foo', 'ipsum']

หมายเหตุ:

  • $amountcount($array)จะต้องมีค่าน้อยกว่าหรือเท่ากับ
  • array_rand()ไม่สับเปลี่ยนคีย์ (ตั้งแต่ PHP 5.2.10 ดู48224 ) ดังนั้นรายการที่คุณเลือกจะอยู่ในลำดับเดิมเสมอ ใช้shuffle()หลังจากนั้นหากจำเป็น


เอกสารประกอบ: array_rand(),shuffle()


แก้ไข:ฟังก์ชั่น Laravel ได้เติบโตขึ้นอย่างเห็นได้ชัดตั้งแต่นั้นมาดู Laravel Arr::random()5.4 นี่คือสิ่งที่ซับซ้อนมากขึ้นซึ่งได้มาจากฟังก์ชัน Laravel ที่โตแล้ว:

function array_random($array, $number = null)
{
    $requested = ($number === null) ? 1 : $number;
    $count = count($array);

    if ($requested > $count) {
        throw new \RangeException(
            "You requested {$requested} items, but there are only {$count} items available."
        );
    }

    if ($number === null) {
        return $array[array_rand($array)];
    }

    if ((int) $number === 0) {
        return [];
    }

    $keys = (array) array_rand($array, $number);

    $results = [];
    foreach ($keys as $key) {
        $results[] = $array[$key];
    }

    return $results;
}

จุดเด่นบางประการ:

  • ยกเว้นหากมีรายการไม่เพียงพอ
  • array_random($array, 1) ส่งคืนอาร์เรย์ของหนึ่งรายการ ( # 19826 )
  • รองรับค่า "0" สำหรับจำนวนรายการ ( # 20439 )

8

array_randฟังก์ชั่นที่ดูเหมือนว่าจะมีการกระจายไม่สม่ำเสมอบนอาร์เรย์ขนาดใหญ่ไม่ได้รายการอาร์เรย์ทุกคนอย่างเท่าเทียมกันมีแนวโน้มที่จะได้รับเลือก การใช้การสุ่มในอาร์เรย์แล้วการใช้องค์ประกอบแรกไม่มีปัญหานี้:

$myArray = array(1, 2, 3, 4, 5);

// Random shuffle
shuffle($myArray);

// First element is random now
$randomValue = $myArray[0];

นั่นเป็น "งาน" ในการคำนวณพิเศษมากมายเพียงเพื่อให้ได้องค์ประกอบแบบสุ่มเพียงชิ้นเดียว คำตอบอื่น ๆ ที่ใช้mt_rand()น่าจะเหมาะกับงานมากกว่า
rinogo

ฉันคิดว่าขึ้นอยู่กับความต้องการของคุณ ในกรณีของฉันการกระจายมีความสำคัญมากและค่าใช้จ่ายในการคำนวณไม่ได้
Asciiom

5

อีกวิธีหนึ่งในการพลิกอาร์เรย์เพื่อรับค่าโดยตรง

เศษเล็กเศษน้อย

$array = [ 'Name1' => 'John', 'Name2' => 'Jane', 'Name3' => 'Jonny' ];
$val = array_rand(array_flip($array));

array_randส่งคืนคีย์ไม่ใช่ค่า ดังนั้นเราจึงพลิกค่าเป็นกุญแจสำคัญ

หมายเหตุ: คีย์ PHP เป็นคีย์เฉพาะดังนั้นเมื่อมีการพลิกอาร์เรย์ค่าที่ซ้ำกันเป็นคีย์จะถูกเขียนทับ


ทำไมไม่ทำ$array[array_rand($array)];?
rinogo

@rinogo ก็ใช้ได้เหมือนกันอันนี้ตอบไปแล้ว สิ่งนี้แตกต่างจากคำตอบของคุณเล็กน้อย array_flipลบรายการที่ซ้ำกันเป็นคีย์จากนั้นให้ผลลัพธ์ ... หมายความว่าไม่ซ้ำกัน!
Smartpal

4
$rand = rand(1,4);

หรือสำหรับอาร์เรย์โดยเฉพาะ:

$array = array('a value', 'another value', 'just some value', 'not some value');
$rand = $array[ rand(0, count($array)-1) ];

2
คุณจะไม่ได้รับรายการแรกในรายการนี้และคุณจะออกไปนอกอาร์เรย์ด้วย 4
Ólafur Waage

แรนด์ $ แรกเกี่ยวกับค่า อาร์เรย์เดิมมีค่าตั้งแต่ 1 ถึง 4 ค่า $ Rand ที่สองเกี่ยวกับคีย์อาร์เรย์ 0 ถึง 3
Josh Davis

3

ในกรณีของฉันฉันต้องได้รับ 2 ค่าสิ่งที่เป็นวัตถุ ฉันแบ่งปันวิธีง่ายๆนี้

$ran = array("a","b","c","d");
$ranval = array_map(function($i) use($ran){return $ran[$i];},array_rand($ran,2));

2

การเลือกของคุณมีผลกระทบด้านความปลอดภัยหรือไม่? ถ้าเป็นเช่นนั้นให้ใช้random_int()และarray_keys(). ( random_bytes()เป็น PHP 7 เท่านั้น แต่มีpolyfill สำหรับ PHP 5 )

function random_index(array $source)
{
    $max = count($source) - 1;
    $r = random_int(0, $max);
    $k = array_keys($source);
    return $k[$r];
}

การใช้งาน:

$array = [
    'apple' =>   1234,
    'boy'   =>   2345,
    'cat'   =>   3456,
    'dog'   =>   4567,
    'echo'  =>   5678,
    'fortune' => 6789
];
$i = random_index($array);
var_dump([$i, $array[$i]]);

การสาธิต: https://3v4l.org/1joB1




2

ฉันต้องการเวอร์ชันหนึ่งบรรทัดสำหรับอาร์เรย์สั้น:

($array = [1, 2, 3, 4])[mt_rand(0, count($array) - 1)]

หรือถ้าอาร์เรย์ได้รับการแก้ไข:

[1, 2, 3, 4][mt_rand(0, 3]

2

On-ซับ:

echo $array[array_rand($array,1)]

แม้ว่ารหัสนี้อาจตอบคำถาม แต่การให้บริบทเพิ่มเติมเกี่ยวกับสาเหตุและ / หรือวิธีที่รหัสนี้ตอบคำถามช่วยเพิ่มมูลค่าในระยะยาว
β.εηοιτ.βε

1

สิ่งนี้จะใช้ได้ดีกับอาร์เรย์ในบรรทัด นอกจากนี้ฉันคิดว่าสิ่งต่างๆเป็นระเบียบเรียบร้อยและสามารถนำกลับมาใช้ใหม่ได้มากขึ้นเมื่อรวมอยู่ในฟังก์ชัน

function array_rand_value($a) {
    return $a[array_rand($a)];
}

การใช้งาน:

array_rand_value(array("a", "b", "c", "d"));

บน PHP <7.1.0 array_rand()ใช้rand()ดังนั้นคุณจึงไม่ต้องการใช้ฟังก์ชันนี้สำหรับสิ่งที่เกี่ยวข้องกับความปลอดภัยหรือการเข้ารหัส บน PHP 7.1.0+ ให้ใช้ฟังก์ชันนี้โดยไม่ต้องกังวลตั้งแต่rand()mt_rand()ได้รับการนามแฝง


0

ฉันอิงตามคำตอบของฉันจากฟังก์ชันของ @ ÓlafurWaage ฉันพยายามใช้ แต่พบปัญหาการอ้างอิงเมื่อฉันพยายามแก้ไขวัตถุส่งคืน ฉันอัปเดตฟังก์ชันของเขาเพื่อส่งต่อและส่งคืนโดยอ้างอิง ฟังก์ชั่นใหม่คือ:

function &random_value(&$array, $default=null)
{
    $k = mt_rand(0, count($array) - 1);
    if (isset($array[$k])) {
        return $array[$k];
    } else {
        return $default;
    }
}

สำหรับบริบทเพิ่มเติมโปรดดูคำถามของฉันที่การส่งต่อ / การส่งคืนการอ้างอิงไปยังวัตถุ + วัตถุที่เปลี่ยนแปลงไม่ทำงาน


0

วิธีง่ายๆในการรับอาร์เรย์ Randdom รูปแบบคุ้มค่า

$color_array =["red","green","blue","light_orange"];
$color_array[rand(0,3)

ตอนนี้ทุกครั้งที่คุณจะได้รับสีที่แตกต่างจากอาร์เรย์


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.