---
title: "Arrays"
description: "One declaration for a run of identical parts — slats, shelves and pickets — with a count that can be computed from a standard."
url: https://kaicad.barpom.xyz/docs/schema/arrays
schema: "0.1"
source: packages/spec/src/design.ts
---

# Arrays

An array expands a joint into a distributed run of one part. It is how you get eighteen slats
from one declaration, with the count computed rather than counted.

```yaml
- id: slats_to_cleats
  kind: butt
  removable: true
  array:
    of: slat
    count: ceil((slat_cleat.blank.length - slat.blank.width) / (slat.blank.width + max_slat_gap)) + 1
    distribute: even
    span: [slat_cleat@left:face.start, slat_cleat@left:face.end]
  mate:
    a: slat:face.bottom
    b: slat_cleat@left:face.left
    align:
      contact: true
      roll: 180
      offset: [-slat_centre_offset, 0, 0]
```

| Key | | |
| --- | --- | --- |
| `of` | required | The part id to repeat. |
| `count` | required | How many. An expression. |
| `span` | | Two anchor paths bounding the run. |
| `distribute` | | `even` or `even_gaps`. |
| `spacing` | | A fixed centre-to-centre distance, instead of a span. |

## `span` plus `distribute`, or `spacing`

**`span` + `distribute`** fills a run between two anchors. Use it when the ends are fixed and
the spacing should fall out — slats between the ends of a cleat, shelves between the top and
bottom of a carcass.

- `even` spaces the parts' **centres** evenly across the span.
- `even_gaps` makes the clear **gaps between** them equal, which is what you want when the
  parts have width and the gap is the thing being checked.

**`spacing`** sets a fixed centre-to-centre distance and lets the run end where it ends. Use it
when the pitch is what matters — shelf pins on the 32 mm system, balusters at a required
maximum gap.

## Compute the count; do not count it

```yaml
count: ceil((slat_cleat.blank.length - slat.blank.width) / (slat.blank.width + max_slat_gap)) + 1
```

That expression reads: divide the run by one slat plus one maximum gap, round up, add the slat
at the far end. Because `max_slat_gap` is derived from `standards.bed.slat_gap_max`, and the
cleat length is derived from the mattress, changing `us-queen` to `uk-super-king` adds slats
by itself and the gap stays legal.

Typing `count: 18` is the version that is wrong the moment anything else moves. It is also the
version that quietly stops satisfying the standard it was sized against, with nothing to say
so.

## The mate is written once, for one part

Inside an array, the mate is written as though there were a single part. The expansion applies
it to each copy in turn and slides them along the span.

```yaml
mate:
  a: slat:face.bottom
  b: slat_cleat@left:face.left
  align:
    contact: true
    roll: 180
    offset: [-slat_centre_offset, 0, 0]
```

That offset slides each slat from the left cleat across to the bed's centre line, so it lands
on **both** cleats rather than hanging off one. It is derived, like everything else, so it
follows the mattress size.

## Arrays or instances?

| Use | When |
| --- | --- |
| [`instances`](/docs/schema/parts#instances) | Two or three copies that sit in different, named places — a left post and a right post. |
| `array` | Many interchangeable copies in a regular run — slats, shelves, pickets. |

Instances are placed by their own joints, one per copy. An array is placed by one joint, and
its count can be an expression. If you are about to write `instances: [a, b, c, d, e, f]`,
write an array instead.

## What the validator does with it

Two things worth knowing.

**Findings are collapsed.** If every slat in a run has the same problem, the report says so
once with the count and the full subject list, rather than eighteen times. Twelve copies of
one problem crowd out the other eleven problems in a context window.

**The gap is checked against the standard, not against your arithmetic.** `DOM-` findings read
`standards.bed.slat_gap_max` directly. If the computed count leaves a gap of 78 mm, the report
gives you the count that would not — with the number in it, ready to paste back.
