select Select Parameter

Complete Guide to ICU Select - Direct Value Lookup

Overview

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.

Basic Example

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:

✅ Select vs Selectordinal vs Plural

select is the simplest parameter type:

How It Works

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.

Select Parameter Structure

{
  "paramName": "gender",
  "type": "select",
  "list": [
    { "value": "male", "text": "He" },
    { "value": "female", "text": "She" },
    { "value": "other", "text": "They" }
  ]
}

Common Use Cases

Gender Selection

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" }
  ]
}

Boolean Values

Select can be used for boolean-like selections:

{
  "paramName": "isActive",
  "type": "select",
  "list": [
    { "value": "true", "text": "Active" },
    { "value": "false", "text": "Inactive" }
  ]
}

Status Messages

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" }
  ]
}

Language Implementation Comparison

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

Generated Code Implementation

TypeScript/JavaScript Implementation

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

Swift Implementation

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
}

Python Implementation

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)

Best Practices

✅ Do: Always Include an "other" Option

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" }
  ]
}

✅ Do: Use Descriptive Value Names

Use clear, descriptive values that make the code readable:

❌ Don't: Use Select for Numeric Rules

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.

Complete Import Example

{
  "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": "未知" }
              ]
            }
          ]
        }
      }
    }
  ]
}