Suponha que eu tenha uma matriz e queira escolher um elemento aleatoriamente.
Qual seria a maneira mais simples de fazer isso?
O caminho óbvio seria array[random index]
. Mas talvez haja algo como o ruby array.sample
? Ou, se não, esse método poderia ser criado usando uma extensão?
array[random number from 0 to length-1]
, mas não consigo encontrar como gerar um int aleatório rapidamente, eu perguntaria no estouro de pilha se não estivesse bloqueado :) Eu não queria poluir a pergunta com meias soluções, quando talvez haja algo como rubyarray.sample
Respostas:
Swift 4.2 e superior
A nova abordagem recomendada é um built-in método no protocolo Coleção:
randomElement()
. Ele retorna um opcional para evitar o caso vazio que assumi anteriormente.Se você não criar a matriz e não tiver uma contagem garantida> 0, faça algo como:
Swift 4.1 e abaixo
Apenas para responder sua pergunta, você pode fazer isso para obter a seleção aleatória de arrays:
As peças são feias, mas acredito que são necessárias, a menos que alguém tenha outra maneira.
fonte
man arc4random
e stackoverflow.com/questions/10984974/…removeRandomElement()
função além derandomElement()
. Seria modeladoremoveFirst()
, mas remova um objeto em um índice aleatório.0..<array.count
(por vários motivos, os principais são que ele não funciona para fatias e é propenso a erros). Você pode fazerlet randomIndex = array.indices.randomElement()
, seguido porlet randomElement = array.remove(at: randomIndex)
. Você pode até incorporarlet randomElement = array.remove(at: array.indices.randomElement())
.Analisando o que Lucas disse, você pode criar uma extensão para a classe Array assim:
Por exemplo:
fonte
T
foi renomeado paraElement
.guard
verificação para ver se a matriz está vazia e depois retornarnil
.arc4random
qualquer ganho de desempenho é completamente insignificante. Eu atualizei a resposta.Versão Swift 4 :
fonte
startIndex != 0
No Swift 2.2, isso pode ser generalizado para que tenhamos:
Primeiro, implementando
random
propriedade estática paraUnsignedIntegerType
s:Então, para
ClosedInterval
s comUnsignedIntegerType
limites:Então (um pouco mais envolvido), para
ClosedInterval
s comSignedIntegerType
limites (usando métodos auxiliares descritos mais abaixo):... onde
unsignedDistanceTo
,unsignedDistanceFromMin
eplusMinIntMax
auxiliares métodos podem ser implementados como segue:Finalmente, para todas as coleções em que
Index.Distance == Int
:... que pode ser otimizado um pouco para o número inteiro
Range
s:fonte
Você pode usar a função aleatória () interna do Swift também para a extensão:
fonte
Outra sugestão do Swift 3
fonte
Os outros respondem, mas com o suporte do Swift 2.
Swift 1.x
Swift 2.x
Por exemplo:
fonte
Uma implementação funcional alternativa com verificação de matriz vazia.
fonte
Aqui está uma extensão em Matrizes com uma verificação de matriz vazia para mais segurança:
Você pode usá-lo tão simples quanto isto :
Se você preferir um Framework que também tenha alguns recursos mais úteis, consulte o HandySwift . Você pode adicioná-lo ao seu projeto via Carthage e usá-lo exatamente como no exemplo acima:
Além disso, também inclui uma opção para obter vários elementos aleatórios ao mesmo tempo :
fonte
Swift 3
importar GameKit
fonte
Swift 3 - simples e fácil de usar.
Criar matriz
Criar cor aleatória
Defina essa cor para o seu objeto
Aqui está um exemplo de um
SpriteKit
projeto que atualiza umSKLabelNode
com um aleatórioString
:fonte
Se você deseja obter mais de um elemento aleatório da sua matriz sem duplicatas , o GameplayKit já cobriu:
Você tem algumas opções de aleatoriedade, consulte GKRandomSource :
fonte
Acho que usar o GKRandomSource.sharedRandom () do GameKit funciona melhor para mim.
ou você pode retornar o objeto no índice aleatório selecionado. Verifique se a função retorna uma String primeiro e, em seguida, retorne o índice da matriz.
Curto e direto ao ponto.
fonte
Há um método interno
Collection
agora:Se você deseja extrair até
n
elementos aleatórios de uma coleção, você pode adicionar uma extensão como esta:E se você quiser que eles sejam exclusivos, você pode usar a
Set
, mas os elementos da coleção devem estar em conformidade com oHashable
protocolo:fonte
O código swift3 mais recente experimenta seu bom funcionamento
fonte
Eu descobri uma maneira muito diferente de fazer isso usando os novos recursos introduzidos no Swift 4.2.
declaramos uma função com parâmetros pegando uma matriz de Strings e retornando uma String.
Então pegamos o ArrayOfStrings em uma variável.
Basicamente, embaralha a matriz de seqüências de caracteres e, em seguida, também seleciona aleatoriamente o número total de contagens e, em seguida, retorna o índice aleatório da matriz embaralhada.
fonte