I'm doing some code generation stuff using Sourcery and Stencil.
I'm trying to add an extension to all my enums that has a method that returns a random case of the enum. So, in my case, I need a way to access a random array element.
I know that we can do array lookup using one of the following ways: (first, last or by index), but I can't find a way to access a random element.
Here is an example of what I'm trying to achieve:
{% for type in types.enums %}
extension {{ type.name }} {
static func random() -> {{ type.name }} {
let index = Int.random(in: 0..<{{ type.cases.count }})
return .{{ type.cases.index.name }}
}
}
{% endfor %}
The previous code snippet doesn't work, obviously. I just added it as a way to make my intention clear.
Does anyone have an idea about this?
So, after the ideas posted by others here (thanks to them). I implemented it like the following as I also need to randomize the associated values of the cases that have associated values:
{% for type in types.enums %}
extension {{ type.name }} {
static func random() -> {{ type.name }} {
let cases: [{{ type.name }}] = [
{% for case in type.cases %}
{% if case.associatedValues.count > 0 %}
{% map case.associatedValues into values using value %}.random(){% endmap %}
.{{ case.name }}({{ values|join:", " }}),
{% else %}
.{{ case.name }},
{% endif %}
{% endfor %}
]
return cases.randomElement()!
}
}
{% endfor %}
The above code snippet iterates over the cases of the enum and creates an array that contains all the cases. If a case has associated values, it will create a random element for each associated value using the random()
method.