# array\_equal

Checks if two arrays contain the same elements (regardless of order). Returns `true` if both arrays have identical elements, `false` otherwise.

```liquid
{% assign array_a = "apple,banana,cherry" | split: "," %}
{% assign array_b = "cherry,apple,banana" | split: "," %}
{% assign array_c = "apple,banana" | split: "," %}

{% if array_a | array_equal: array_b %}
  Arrays A and B are equal
{% endif %}

{% unless array_a | array_equal: array_c %}
  Arrays A and C are different
{% endunless %}
```

Output:

```
Arrays A and B are equal
Arrays A and C are different
```

#### Syntax

```liquid
{{ arrayA | array_equal: arrayB }}
```

| Parameter | Description             |
| --------- | ----------------------- |
| `arrayA`  | First array             |
| `arrayB`  | Second array to compare |

#### Return Value

| Condition                 | Result  |
| ------------------------- | ------- |
| Same elements (any order) | `true`  |
| Different lengths         | `false` |
| Different elements        | `false` |
| Either input not an array | Error   |

#### Examples

**Verify tag synchronization:**

```liquid
{% assign shopify_tags = product.tags | split: ", " | sort %}
{% assign expected_tags = erp_product.tags | sort %}

{% if shopify_tags | array_equal: expected_tags %}
  {% log "Tags are in sync" %}
{% else %}
  {% log "Tag mismatch detected - syncing..." %}
  {% comment %} Update tags {% endcomment %}
{% endif %}
```

**Check if permissions unchanged:**

```liquid
{% assign current_permissions = user.permissions %}
{% assign required_permissions = role.default_permissions %}

{% if current_permissions | array_equal: required_permissions %}
  {% log "User has standard permissions for role" %}
{% else %}
  {% log "User has custom permissions" %}
{% endif %}
```

**Validate order contents:**

```liquid
{% assign ordered_skus = order.line_items | map: "sku" | sort %}
{% assign expected_skus = subscription.items | map: "sku" | sort %}

{% if ordered_skus | array_equal: expected_skus %}
  {% log "Order matches subscription exactly" %}
{% else %}
  {% log "Order differs from subscription" %}

  {% assign missing = expected_skus | array_difference: ordered_skus %}
  {% assign extra = ordered_skus | array_difference: expected_skus %}

  {% if missing.size > 0 %}
    {% log "Missing items: " | append: missing | join: ", " %}
  {% endif %}

  {% if extra.size > 0 %}
    {% log "Extra items: " | append: extra | join: ", " %}
  {% endif %}
{% endif %}
```

**Compare collection contents:**

```liquid
{% assign collection_a_ids = collection_a.products | map: "id" | sort %}
{% assign collection_b_ids = collection_b.products | map: "id" | sort %}

{% if collection_a_ids | array_equal: collection_b_ids %}
  {% log "Collections contain the same products" %}
{% else %}
  {% log "Collections have different products" %}
{% endif %}
```

**Detect configuration changes:**

```liquid
{% assign current_config = "feature_a,feature_b,feature_c" | split: "," %}
{% assign saved_config = shop_metafield.value | split: "," %}

{% unless current_config | array_equal: saved_config %}
  {% log "Configuration has changed - saving..." %}

  {% comment %} Save new configuration {% endcomment %}
  {% json metafield_input %}
    {
      "metafields": [{
        "ownerId": "{{ shop.id }}",
        "namespace": "config",
        "key": "features",
        "value": "{{ current_config | join: "," }}",
        "type": "single_line_text_field"
      }]
    }
  {% endjson %}

  {% graphql query: metafields_set, variables: metafield_input as result %}
{% endunless %}
```

**Conditional processing based on array state:**

```liquid
{% assign empty_array = "[]" | parse %}
{% assign results = api_response.items | default: empty_array %}

{% if results | array_equal: empty_array %}
  {% log "No results returned from API" %}
{% else %}
  {% log "Processing " | append: results.size | append: " results" %}
  {% for item in results %}
    {% comment %} Process item {% endcomment %}
  {% endfor %}
{% endif %}
```

#### Important Notes on Comparison

**Order does not matter:**

```liquid
{% assign a = "1,2,3" | split: "," %}
{% assign b = "3,2,1" | split: "," %}
{{ a | array_equal: b }}  {% comment %} true {% endcomment %}
```

**Duplicates matter:**

```liquid
{% assign a = "1,2,2,3" | split: "," %}
{% assign b = "1,2,3" | split: "," %}
{{ a | array_equal: b }}  {% comment %} false (different lengths) {% endcomment %}
```

**Type matters (strict equality):**

```liquid
{% assign a = "[1, 2, 3]" | parse %}
{% assign b = "['1', '2', '3']" | parse %}
{{ a | array_equal: b }}  {% comment %} false (numbers vs strings) {% endcomment %}
```

#### Notes

* Both inputs must be arrays; throws error otherwise
* Comparison is order-independent (set equality)
* Uses strict equality (===) for element comparison
* Arrays with different lengths are immediately `false` (fast path)
* For order-sensitive comparison, convert to strings: `arrayA | join: "," == arrayB | join: ","`
* See also: `array_difference`, `array_intersection`, `array_symmetric_difference`
