Como obter valor aleatório de uma matriz?

123

Eu tenho uma matriz chamada $ran = array(1,2,3,4);

Preciso obter um valor aleatório dessa matriz e armazená-lo em uma variável. Como posso fazer isso?

Elitmiar
fonte

Respostas:

232

Você também pode fazer exatamente:

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

Esta é a maneira de fazer isso quando você tem uma matriz associativa.

reko_t
fonte
11
de acordo com este comentário array_rand não é tão aleatório como deveria ser
Timo Huovinen
1
Ou você pode exigir este pacote e usar #array_rand_value
murze
10
Desde o PHP 7.1, array_rand()usa o gerador Mersenne Twister: rand () com alias para mt_rand () e srand () com alias para mt_srand () . Na prática, agora deve ser bom o suficiente.
Gras Double
32

O PHP fornece uma função exatamente para isso: array_rand ()
http://php.net/manual/en/function.array-rand.php

$ran = array(1,2,3,4);
$randomElement = $ran[array_rand($ran, 1)];
NDM
fonte
3
O valor padrão do segundo argumento da array_randfunção é, 1portanto, não é necessário escrevê-lo.
Nabi KAZ
23

Você pode usar mt_rand ()

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

Isso também é útil como uma função se você precisar do valor

function random_value($array, $default=null)
{
    $k = mt_rand(0, count($array) - 1);
    return isset($array[$k])? $array[$k]: $default;
}
Ólafur Waage
fonte
4
Deve ser mt_rand (0, 3), pois existem apenas 4 itens. Mais corretamente: $ array [mt_rand (0, count ($ array)]
reko_t 29/10/2009
2
Err, eu acho que você quis mt_rand (0, count ($ RAN) - 1)
Josh Davis
de acordo com comentários PHP array_randnão é tão aleatório como deveria ser, por isso, mt_randé o preferido
Timo Huovinen
1
Qual é o sentido de toda a issetparte? Isso falharia para matrizes associativas de qualquer maneira.
Luke Cousins
eu não sei por que, mas quando se usa mt_randem vez de rand, neste caso, parece preferir alguns itens mais do que os outros
user151496
20
$value = $array[array_rand($array)];
KAS
fonte
14

Você pode usar a função array_rand para selecionar uma chave aleatória da sua matriz como abaixo.

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

ou você pode usar as funções rand e count para selecionar um índice aleatório.

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

Derivado do 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;
}

Uso:

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

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

Algumas notas:

  • $amounttem que ser menor ou igual a count($array).
  • array_rand()não embaralha as teclas (desde o PHP 5.2.10, consulte 48224 ); portanto, os itens escolhidos sempre estarão na ordem original. Use shuffle()depois, se necessário.


Documentação: array_rand(),shuffle()


edit: A função Laravel cresceu visivelmente desde então, veja Laravel 5.4's Arr::random(). Aqui está algo mais elaborado, derivado da função Laravel adulta:

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;
}

Alguns destaques:

  • Lançar exceção se não houver itens suficientes disponíveis
  • array_random($array, 1)retorna uma matriz de um item ( # 19826 )
  • Valor de suporte "0" para o número de itens ( # 20439 )
Gras Double
fonte
8

A array_randfunção parece ter uma distribuição desigual em matrizes grandes, nem todos os itens da matriz têm a mesma probabilidade de serem selecionados. Usar o shuffle na matriz e, em seguida, pegar o primeiro elemento não tem esse problema:

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

// Random shuffle
shuffle($myArray);

// First element is random now
$randomValue = $myArray[0];
Asciiom
fonte
Isso é um monte de "trabalho" computacional extra apenas para obter um único elemento aleatório. As outras respostas usadas mt_rand()provavelmente são mais adequadas para a tarefa.
Rinogo 2/05/19
Depende de quais são suas necessidades, suponho. No meu caso, a distribuição foi muito importante e a sobrecarga computacional não.
Asciiom
5

Outra abordagem através da inversão da matriz para obter valor direto.

Snippet

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

array_randchave de retorno não valor. Então, estamos lançando valor como chave.

Nota: A chave PHP sempre é uma chave exclusiva; portanto, quando a matriz é invertida, o valor duplicado como uma chave será substituído.

Smartpal
fonte
Por que não apenas fazer $array[array_rand($array)];?
rinogo 12/03/19
@rinogo Também funciona, isso já foi respondido acima. Isso é um pouco diferente da sua resposta, array_flipremova o duplicado como chave e dê o resultado ... Significa que não há duplicado!
Smartpal
4
$rand = rand(1,4);

ou, para matrizes especificamente:

$array = array('a value', 'another value', 'just some value', 'not some value');
$rand = $array[ rand(0, count($array)-1) ];
Duroth
fonte
2
Você nunca obteria o primeiro item desta lista e sairia da matriz com 4
Ólafur Waage
O primeiro $ rand é sobre valores. A matriz original tem valores que variam de 1 a 4. A segunda $ rand é sobre chaves do array, 0 a 3.
Josh Davis
3

No meu caso, eu tenho que obter 2 valores o que são objetos. Eu compartilho esta solução simples.

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

Sua seleção tem implicações de segurança? Se sim, use random_int()e array_keys(). ( random_bytes()é apenas PHP 7, mas existe um polyfill para o PHP 5 ).

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

Uso:

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

Demonstração: https://3v4l.org/1joB1

Scott Arciszewski
fonte
2

Use rand () para obter um número aleatório para repetir uma tecla aleatória. Ex: 0 - 3

$ran = array(1,2,3,4);
echo $ran[rand(0,3)];
Muhammad Ibnuh
fonte
2

Uma linha: $ran[rand(0, count($ran) - 1)]

Abdelilah
fonte
2

Eu precisava de uma versão de linha para uma matriz curta:

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

ou se o array for fixo:

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

On-liner:

echo $array[array_rand($array,1)]
Sid
fonte
Embora esse código possa responder à pergunta, fornecer um contexto adicional a respeito de por que e / ou como esse código responde à pergunta melhora seu valor a longo prazo.
β.εηοιτ.βε
1

Isso funcionará bem com matrizes em linha. Além disso, acho que as coisas são mais arrumadas e reutilizáveis ​​quando envolvidas em uma função.

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

Uso:

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

No PHP <7.1.0, array_rand()usarand() , então você não gostaria dessa função para nada relacionado à segurança ou criptografia. No PHP 7.1.0+, use esta função sem preocupações, pois rand()foi aliasada amt_rand() .

rinogo
fonte
0

Estou baseando minha resposta na função do @ ÓlafurWaage. Tentei usá-lo, mas estava com problemas de referência quando tentava modificar o objeto de retorno. Atualizei sua função para passar e retornar por referência. A nova função é:

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

Para obter mais contexto, consulte minha pergunta em Passagem / retorno de referências ao objeto + alteração do objeto não está funcionando

Jeff
fonte
0

Uma maneira simples de obter o valor Randdom do formulário Array .

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

agora toda vez que você obter cores diferentes da matriz .

pankaj kumar
fonte
-5

Você obtém um número aleatório de uma matriz da seguinte maneira:

$randomValue = $rand[array_rand($rand,1)];
Adam Libonatti-Roche
fonte
4
array_rand () retorna uma chave aleatória, não um valor aleatório.
21129 reko_t