Умный способ выбрать случайную функцию

#swift #function #random

#swift #функция #Случайный

Вопрос:

Я пытаюсь выбрать и запустить случайную функцию в swift.

В настоящее время я реализовал случай переключения, подобный этому

   switch Int.random(in: 1...2) {
                            case 1:   functionOne()
                            case 2:   functionTwo()
                            default:  print("error")
                            }
 

если есть больше опций, код становится действительно избыточным.

Как я могу улучшить код, чтобы сохранить дополнительные строки? Оптимальным было бы:

   [functionOne(), functionTwo()].randomElement()
 

Это не работает, а просто запускает последний элемент в массиве.
Есть ли способ поместить функции в массив и позволить им работать?

Комментарии:

1. Учитывая ли это, что ни одна из ваших функций в вашем пуле не принимает разные типы параметров? В противном случае этот механизм вообще не будет работать

2. ([functionOne, functionTwo].randomElement()!)()

3. я думаю, что @matt находится на хорошем пути, в настоящее время у меня нет возможности проверить это, но для этого ни одна из функций не должна возвращаться nil

4. Если у вас есть только 2 случая, зачем вам нужно 100 случайных чисел? Это потому, что вы считаете random(in: 1...100) более случайным, чем random(in: 1...2) ?

5. @matt учитывая то, что сказал OP, может быть больше случаев, чем два, показанных в примере. Я предполагаю, что пул содержит переменное количество функций теоретически до 100

Ответ №1:

Если вы хотите, чтобы вероятность разных функций была разной, то ваш оператор switch был бы хорошим выбором:

 switch Int.random(in: 1...100) {
                        case 1...10:   functionOne() //10% of calls
                        case 11...100: functionTwo() //90% of calls 
                        default:       noFunction()
                        }
 

Если вы хотите, чтобы все они были одинаково вероятными, тогда подход Мэтта кажется более чистым:

 let functions = [functionOne, functionTwo]
(functions.randomElement()!)()
 

Комментарии:

1. отлично, что работает, кто-нибудь может объяснить, зачем нам нужен (!), А первоначальная версия не работала? ([functionOne, FunctionTwo].randomElement()!)() против [functionOne(), FunctionTwo()].randomElement()

2.@NathanaelTse randomElement возвращает значение an Optional , поскольку его вызов возвращает пустое Array nil значение. Вот почему принудительное развертывание безопасно, когда вы вызываете его в непустом массиве. Ваша версия не сработала, потому что вы выполнили функции и просто поместили их Void результаты в массив, при этом [functionOne, functionTwo]... создается массив замыканий и () выполняются замыкания (функции), вот почему вам нужен () после вызова randomElement , поскольку вы хотите выполнить только одну выбранную функцию, а не все изих.