# Dictionaries

Dictionaries in RuLA are collections of key-value pairs. Each key is unique and maps to a value. Keys are strings, while values can be any type.

## Creating Dictionaries

Use curly braces with `key: value` pairs:

```
{'name': 'John', 'age': 30}
{'x': 1, 'y': 2, 'z': 3}
{}                                      # Empty dictionary
{'items': ['a', 'b'], 'count': 2}       # Nested list
```

{% hint style="info" %}
**New in Atfinity 17:** A bare identifier in a dictionary literal is shorthand for `key: 'key'`. See [Dictionary shorthand](/rule-language/operators/dictionary-operators/shorthand.md).

```
{a, b}                  // => {'a': 'a', 'b': 'b'}
{a, b: 'two', c}        // => {'a': 'a', 'b': 'two', 'c': 'c'}
```

{% endhint %}

## Accessing Dictionary Values

Access values by their key using square brackets:

```
person = {'name': 'John', 'age': 30}
person['name']          # Returns 'John'
person['age']           # Returns 30
```

## Dictionary Manipulation

### Checking for Keys

```
person = {'name': 'John', 'age': 30}

'name' in person        # Returns True
'address' in person     # Returns False
'address' not in person # Returns True
```

### Getting All Keys

```
person = {'name': 'John', 'age': 30}
person.keys()           # Returns ['name', 'age']
```

### Counting Entries

```
COUNT(person)           # Returns 2 (number of key-value pairs)
```

## Useful Dictionary Functions

| Function                                                                                                       | Description                                                          | Example                                     |
| -------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | ------------------------------------------- |
| [`keys()`](/rule-language/operators/dictionary-operators/in-1.md)                                              | Get all keys as a list                                               | `{'a': 1, 'b': 2}.keys()` → `['a', 'b']`    |
| [`COUNT`](/rule-language/operators/list-operators/count.md)                                                    | Number of key-value pairs                                            | `COUNT({'a': 1, 'b': 2})` → `2`             |
| [`to_dict`](/rule-language/operators/dictionary-operators/to_dict.md) *(new in Atfinity 17)*                   | Build a dictionary from selected instance attributes                 | `p.to_dict({first_name, last_name})`        |
| [`pick`](/rule-language/operators/dictionary-operators/pick.md) *(new in Atfinity 17)*                         | Return a dictionary with only the selected keys (optionally renamed) | `{'a': 1, 'b': 2}.pick({a})` → `{'a': 1}`   |
| [`merge_dicts` (or `\|`)](/rule-language/operators/dictionary-operators/merge_dicts.md) *(new in Atfinity 17)* | Merge any number of dictionaries (later wins)                        | `{'a': 1} \| {'b': 2}` → `{'a': 1, 'b': 2}` |

## Dictionary Operations

### Working with Lists of Dictionaries

```
people = [
    {'name': 'Alice', 'age': 30},
    {'name': 'Bob', 'age': 25}
]

# Extract a field from each dictionary
MAP(people, p => p['name'])     # Returns ['Alice', 'Bob']

# Filter by a field
FILTER(people, p => p['age'] > 25)  # Returns [{'name': 'Alice', 'age': 30}]

# Sort by a field
SORT(people, 'age')            # Returns [{'name': 'Bob', ...}, {'name': 'Alice', ...}]
```

## Checking Dictionary Contents

```
person = {'name': 'John', 'city': 'Zurich'}

# Check if key exists
'name' in person                # True
'email' not in person           # True

# Use in conditions
if 'city' in person then person['city'] else 'Unknown' end
```

## Nested Structures

Dictionaries can contain other complex types:

```
order = {
    'id': 123,
    'items': [
        {'product': 'Book', 'price': 15},
        {'product': 'Pen', 'price': 3}
    ],
    'customer': {
        'name': 'Jane',
        'email': 'jane@example.com'
    }
}

# Access nested values
order['items'][0]['product']    # Returns 'Book'
order['customer']['name']       # Returns 'Jane'

# Calculate total
prices = MAP(order['items'], item => item['price'])
SUM(prices)                     # Returns 18
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.atfinity.io/rule-language/data-types/dictionaries.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
