Complete Guide to ICU Select - Direct Value Lookup
The select parameter type is the simplest ICU parameter type - it performs a direct value lookup in a predefined list. Unlike plural or selectordinal, there are no language-specific rules or numeric calculations involved.
Content: "@{genderText} is online"
Params:
{
"paramName": "genderText",
"type": "select",
"options": { "type": "gender" },
"list": [
{ "value": "male", "text": "He" },
{ "value": "female", "text": "She" },
{ "value": "other", "text": "They" }
]
}
Expected Output:
male → "He is online"female → "She is online"other → "They are online"select is the simplest parameter type:
Select parameter works by matching the input value against the value field of each item in the list, then returning the corresponding text field. If no match is found, the original value is returned.
{
"paramName": "gender",
"type": "select",
"list": [
{ "value": "male", "text": "He" },
{ "value": "female", "text": "She" },
{ "value": "other", "text": "They" }
]
}
The most common use case for select is gender-based text selection:
{
"paramName": "gender",
"type": "select",
"list": [
{ "value": "male", "text": "He" },
{ "value": "female", "text": "She" },
{ "value": "other", "text": "They" }
]
}
Select can be used for boolean-like selections:
{
"paramName": "isActive",
"type": "select",
"list": [
{ "value": "true", "text": "Active" },
{ "value": "false", "text": "Inactive" }
]
}
Select is ideal for status-based messages:
{
"paramName": "status",
"type": "select",
"list": [
{ "value": "pending", "text": "Your request is pending" },
{ "value": "approved", "text": "Your request was approved" },
{ "value": "rejected", "text": "Your request was rejected" }
]
}
Since select is the simplest parameter type with no language-specific rules, all languages implement it consistently using a straightforward key-value lookup pattern.
| Language | Implementation | Pattern |
|---|---|---|
| TypeScript | Builds options object, returns options[value] ?? value | Object lookup |
| JavaScript | Builds options object, returns options[value] ?? value | Object lookup |
| Java | Iterates through list, returns matching text or value | Linear search |
| Kotlin | Iterates through list, returns matching text or value | Linear search |
| Swift | Iterates through list, returns matching text or value | Linear search |
| Python | Builds dict, returns options.get(value, value) | Dict lookup |
| Go | Iterates through list, returns matching text or value | Linear search |
| Rust | Iterates through list, returns matching text or value | Linear search |
| Dart | Iterates through list, returns matching text or value | Linear search |
The generated TypeScript code builds an options object for O(1) lookup:
function formatSelect(value: string, p: any): string {
const options: Record = {};
if (p.list) { p.list.forEach((item: any) => options[item.value] = item.text); }
const opt = options[value];
return opt ?? value;
}
The generated Swift code iterates through the list to find a match:
static func formatSelect(_ value: String, _ p: I18NParam) -> String {
guard let list = p.list else { return value }
for item in list {
if item.value == value {
return item.text
}
}
return value
}
The generated Python code builds a dictionary for O(1) lookup:
@staticmethod
def format_select(value: str, p: dict) -> str:
options = {}
if p.get("list"):
for item in p["list"]:
options[item["value"]] = item["text"]
return options.get(value, value)
As a best practice, always include an other option as a fallback for values you may not have explicitly handled:
{
"paramName": "gender",
"type": "select",
"list": [
{ "value": "male", "text": "He" },
{ "value": "female", "text": "She" },
{ "value": "other", "text": "They" }
]
}
Use clear, descriptive values that make the code readable:
"value": "male" instead of "value": "m""value": "pending" instead of "value": "0"Don't use select when you need language-specific numeric rules. If you need to handle plural forms (0, 1, 2, many) use plural. If you need ordinal numbers (1st, 2nd, 3rd) use selectordinal.
{
"strings": [
{
"key": "user.status",
"translations": {
"en-US": {
"content": "@{genderText} is now @{statusText}.",
"params": [
{
"paramName": "genderText",
"type": "select",
"options": { "type": "gender" },
"list": [
{ "value": "male", "text": "He" },
{ "value": "female", "text": "She" },
{ "value": "other", "text": "They" }
]
},
{
"paramName": "statusText",
"type": "select",
"options": { "type": "status" },
"list": [
{ "value": "active", "text": "active" },
{ "value": "inactive", "text": "inactive" },
{ "value": "other", "text": "unknown" }
]
}
]
},
"zh-CN": {
"content": "@{genderText}现在是@{statusText}状态。",
"params": [
{
"paramName": "genderText",
"type": "select",
"options": { "type": "gender" },
"list": [
{ "value": "male", "text": "他" },
{ "value": "female", "text": "她" },
{ "value": "other", "text": "他们" }
]
},
{
"paramName": "statusText",
"type": "select",
"options": { "type": "status" },
"list": [
{ "value": "active", "text": "活跃" },
{ "value": "inactive", "text": "不活跃" },
{ "value": "other", "text": "未知" }
]
}
]
}
}
}
]
}