# concat

Concatenates two arrays together or appends elements to an array. Returns a new array without modifying the original arrays.

```liquid
{% assign fruits = "apple,banana" | split: "," %}
{% assign more_fruits = "cherry,date" | split: "," %}

{% assign all_fruits = fruits | concat: more_fruits %}
{% log all_fruits | join: ", " %}
```

Output:

```
apple, banana, cherry, date
```

#### Syntax

```liquid
{{ array | concat: other_array }}
{{ array | concat: element }}
```

| Parameter     | Description                               |
| ------------- | ----------------------------------------- |
| `array`       | The base array                            |
| `other_array` | Array to append, or single element to add |

#### Examples

**Combine two arrays:**

```liquid
{% assign domestic_orders = orders | where: "shipping_country", "US" %}
{% assign international_orders = orders | where: "shipping_country", "CA" %}

{% assign north_america_orders = domestic_orders | concat: international_orders %}

{% log "Total North America orders: " | append: north_america_orders.size %}
```

**Build array from multiple sources:**

```liquid
{% assign all_products = "[]" | parse %}

{% for collection in collections %}
  {% assign collection_products = collection.products %}
  {% assign all_products = all_products | concat: collection_products %}
{% endfor %}

{% log "Total products across all collections: " | append: all_products.size %}
```

**Merge GraphQL pagination results:**

```liquid
{% assign all_variants = "[]" | parse %}
{% assign cursor = "null" | parse %}

{% for n in (0..100) %}
  {% graphql query: variants_query, variables: vars as result %}

  {% assign page_variants = result.productVariants.edges | map: "node" %}
  {% assign all_variants = all_variants | concat: page_variants %}

  {% unless result.productVariants.pageInfo.hasNextPage %}
    {% break %}
  {% endunless %}

  {% assign cursor = result.productVariants.edges.last.cursor %}
{% endfor %}

{% log "Fetched " | append: all_variants.size | append: " variants" %}
```

**Combine tags from multiple products:**

```liquid
{% assign all_tags = "[]" | parse %}

{% for product in products %}
  {% assign product_tags = product.tags | split: ", " %}
  {% assign all_tags = all_tags | concat: product_tags %}
{% endfor %}

{% assign unique_tags = all_tags | uniq | sort %}
{% log "Unique tags: " | append: unique_tags | join: ", " %}
```

**Add single element to array:**

```liquid
{% assign items = "[]" | parse %}

{% if condition_a %}
  {% assign items = items | concat: "item_a" %}
{% endif %}

{% if condition_b %}
  {% assign items = items | concat: "item_b" %}
{% endif %}

{% log items %}
```

**Merge line items from multiple orders:**

```liquid
{% assign all_line_items = "[]" | parse %}

{% for order in orders %}
  {% assign all_line_items = all_line_items | concat: order.line_items %}
{% endfor %}

{% log "Total line items: " | append: all_line_items.size %}
```

**Combine API responses:**

```liquid
{% assign all_results = "[]" | parse %}

{% for endpoint in endpoints %}
  {% http url: endpoint as response %}
  {% if response.ok and response.body.items %}
    {% assign all_results = all_results | concat: response.body.items %}
  {% endif %}
{% endfor %}
```

**Build notification recipients:**

```liquid
{% assign recipients = "[]" | parse %}

{% comment %} Add order customer {% endcomment %}
{% assign recipients = recipients | concat: order.customer.email %}

{% comment %} Add store admins {% endcomment %}
{% assign admin_emails = "admin@store.com,manager@store.com" | split: "," %}
{% assign recipients = recipients | concat: admin_emails %}

{% comment %} Add vendor if applicable {% endcomment %}
{% if order.vendor_email %}
  {% assign recipients = recipients | concat: order.vendor_email %}
{% endif %}

{% assign unique_recipients = recipients | uniq %}
{% log "Sending to: " | append: unique_recipients | join: ", " %}
```

#### Comparison: concat vs push

| Feature           | `concat`                 | `push`                            |
| ----------------- | ------------------------ | --------------------------------- |
| Modifies original | No (returns new array)   | Yes (mutates in place)            |
| Can add arrays    | Yes (flattens one level) | No (adds array as single element) |
| Use case          | Merging arrays           | Adding single items               |

**Example difference:**

```liquid
{% assign arr = "[1, 2]" | parse %}
{% assign to_add = "[3, 4]" | parse %}

{% comment %} concat - merges arrays {% endcomment %}
{% assign result_concat = arr | concat: to_add %}
{{ result_concat | json }}
{% comment %} Output: [1, 2, 3, 4] {% endcomment %}

{% comment %} push - adds as single element {% endcomment %}
{% push arr, to_add %}
{{ arr | json }}
{% comment %} Output: [1, 2, [3, 4]] {% endcomment %}
```

#### Performance Tip

When building large arrays in a loop, `concat` creates a new array each time. For better performance with many iterations, consider using `push` which modifies in place:

```liquid
{% comment %} Less efficient (many array copies) {% endcomment %}
{% assign result = "[]" | parse %}
{% for item in large_array %}
  {% assign result = result | concat: item %}
{% endfor %}

{% comment %} More efficient (in-place modification) {% endcomment %}
{% assign result = "[]" | parse %}
{% for item in large_array %}
  {% push result, item %}
{% endfor %}
```

#### Notes

* Returns a new array; original arrays are not modified
* When concatenating arrays, elements are flattened one level deep
* When concatenating a single value, it's added as-is
* Works with any array types (strings, numbers, objects)
* For adding single items in a loop, prefer `push` for better performance
* See also: `push` for in-place array modification
