# Path Expressions

Airscript's **Path Expressions** describe the path that must be taken in order to access values stored within Lists, Objects, or any nested combination thereof.

While it is possible to use Path expressions to filter Lists of Objects by using simple queries to define the desired List index, more complex filtering must be done via [Query Expressions](query-expressions).

## Lists

In Path Expressions, items in a List are referenced by their index number, which is delineated by square brackets.

To showcase how Path Expressions are used to access items in a List, assume the following examples have access to the following List of Numbers, called `example_list`:

```json
example_list=[1,2,3,4,5,6]
```

### Indexing Begins at 0

In Airscript, List indexing begins at zero. This means that the first item in a List will be referenced by the index number 0, the second item in a List will be referenced by the index number 1, and so on:

```json
example_list[0] -> 1
example_list[1] -> 2
example_list[2] -> 3
```

### Slicing Lists

Lists can be sliced using the following syntax, where `listName` is the name of the List, `indexFrom` is the index of the item the sliced List will begin with, and `indexTo` is the index of the item the sliced List will end with.

```javascript
listName[indexFrom:indexTo]
```

Note that the values of `indexFrom` and `indexTo` are inclusive. For example, the index `[1:3]` returns the second, third, and forth items in a List:

```json
example_list[1:3] -> [2,3,4]
```

### Nested Lists

The items in a List can be Lists themselves. For instance, the List `nested_list` contains two items. The first is a List of Numbers, and the second is a List of strings:

```json
nested_list -> [
  [
    1,
    2,
    3
  ],
  [
    "one",
    "two",
    "three"
  ]
]
```

The first item in the second List would then be accessed via the following Path Expression:

```json
nested_list[1][0] -> "one"
```

The `*` symbol can be used as an index value to refer to all items in a List. Defining the index value in this way will return a new List, where each item corresponds the value that each item in the indexed List led to:

```javascript
nested_list[*][0] -> [
  1,
  "one"
]
```

## Objects

In Path Expressions, Object properties are referenced by Dot Notation.

To showcase how Path Expressions are used to access properties in an Object, assume all following examples have access to the following Object, `example_object`:

```json
 example_object = {
  "id": 284792,
  "names": {
    "last_name": "Smith",
    "first_name:": "Alice"
  }
}
```

### Dot Notation

Dot Notation can be used to access the value of any attribute within an Object. The name of the Object is listed first, followed by a period and then the name of the relevant Object property.

The property in question can be of any data type. For instance, the `id` property of `example_object`, a Number, is accessed as follows:

```json
example_object.id -> 284792
```

The `names` property of `example_object` is accessed in the same way, even though the returned value is another Object rather than a simple Number:

```json
example_object.names -> {
  "last_name": "Smith",
  "first_name:": "Alice"
}
```

### Nested Objects

Objects can contain other Objects as properties, and Dot Notation can be used to describe the path required to reach individual values within nested Objects. For instance, the property `first_name` in the Object `names`, itself a property of the Object `example_object`, would be accessed as follows:

```json
example_object.names.first_name -> "Alice"
```

## Nested Combinations of Objects and Lists

The principles of accessing values within individual Lists or Objects can be combined in order to access values within nested combinations of Lists and Objects. This can be conceptualized as describing the "path" required to access the desired value.

For instance, consider the following List of Objects. One of the Objects in this List contains another Object (`information`), which contains another Object (`names`), which contains a List (`middle_names`):

```json
example_data = [
  {
    "id": 178373,
    "information": null
  },
  {
    "id": 284792,
    "information": {
      "names": {
        "last_name": "Smith",
        "first_name:": "Alice",
        "middle_names": [
          "Carol",
          "Jane"
        ]
      }
    }
  },
  {
    "id": 273850,
    "information": null
  }
]
```

Accessing a middle name from this List within an Object within an Object within an Object within a List can be done with the following Path Expression:

```json
example_data[1]
  .information
  .names
  .middle_names
  [0] -> "Carol"
```

If an index value is assigned to a List such that it will refer to multiple items in the List, a List will also be returned. For instance, the syntax used to slice a List can be used inside of a Path Expression to return individual properties of the relevant Listed Objects:

```javascript
example_data[1:2].id -> [
  284792,
  273850
]
```

The `*` symbol can be used to define the index of a List:

```javascript
example_data[*].id -> [
  178373,
  284792,
  273850
]
```

## Filtering with Path Expressions

Given a Lists of Objects, a Path Expression can be used to filter and return only the items that fulfill simple criteria. This is done by defining the index not by a number, but by a simple query.

In its most general form, this syntax looks as follows, where `list` is a List of Objects and `CONDITIONAL` is a conditional expression that evaluates to a Boolean. In order to be useful, this conditional should evaluate differently for each item in the List. To facilitate this, the symbol `@` can be used as a placeholder for each Object in the List, such as in the following example:

```json
list[?(CONDITIONAL_EXPRESSION(@)]
```

This will return all items in the List where the `CONDITIONAL_EXPRESSION` expression evaluates to `TRUE`.

To demonstrate this syntax, assume all of the following examples have access to the List of Objects, `list_of_books`:

```javascript
list_of_books = [
  {
    title: "Angels & Demons",
    author: "Dan Brown",
    isbn: "9781416524793",
    genres: [ "Fiction" ]
  },
  {
    title: "The Da Vinci Code",
    author: "Dan Brown",
    isbn: "9780307879257",
    genres: [ "Fiction" ]
  },
  {
    title: "Hackers: Heroes of the Computer Revolution",
    author: "Steven Levy",
    isbn: "9780141000510",
    genres: [
      "History",
      "Nonfiction"
    ]
  },
  {
    title: "Moonwalking with Einstein: The Art and Science of Remembering Everything",
    author: "Joshua Foer",
    isbn: "9781594202292",
    genres: [ "Nonfiction" ]
  }
]

```

The following example returns all the Objects in `list_of_books` where the `author` property is equal to "Dan Brown". Notice how the `@` symbol is used in Dot Notation to refer to a property in each Object in the given List:

```javascript
list_of_books[?(@.author = "Dan Brown")] -> [
  { 
    title: "Angels & Demons"
    author: "Dan Brown"
    isbn: "9781416524793"
    genres: ["Fiction"]
  },
  {
    title: "The Da Vinci Code",
    author: "Dan Brown",
    isbn: "9780307879257",
    genres: ["Fiction"]
  }
]
```

There are many ways to create conditional expressions. For a more detailed dive into what sort of conditional expressions are available out-of-the-box, see the reference documentation on [Conditional Functions](../../../airscript-expressions/conditional-functions/equal) and [Comparison Operators](../../../airscript-expressions/comparison-operators).

As an example of a Path Expression that contains an Airscript Function within it, consider how the [CONTAINS](../../../airscript-expressions/list-functions/contains) function can be used to filter a List of Objects by the contents of a List nested within each Object:

```json
list_of_books[
  ?(CONTAINS(
    @.genres,
    "Nonfiction"
  ))
  ] -> [
  {
    "title": "Hackers: Heroes of the Computer Revolution",
    "author": "Steven Levy",
    "isbn": "9780141000510",
    "genres": [
      "History",
      "Nonfiction"
    ]
  },
  {
    "title": "Moonwalking with Einstein: The Art and Science of Remembering Everything",
    "author": "Joshua Foer",
    "isbn": "9781594202292",
    "genres": [
      "Nonfiction"
    ]
  }
]
```
