Skip to content

CollectionTable ​

<CollectionTable expr="Subsets(4)"> -- the chrome around a <table-view-box>: the editors for the collection, its columns and a filter, and the table they drive. The table asks the page's kernel only for the rows in view, so SymmetricGroup(25) scrolls as cheaply as Subsets(4) and NonNegativeIntegers scrolls without end. The # column is the index that reproduces each row, At(expr, #).

columns names statistics to apply to every row -- a head (Descents) or any expression over the row _ (Max(_) - Min(_)), comma-separated, addable and removable live. filter is a predicate over _; it is answered like Filter, by a scan the kernel runs in slices, so the count is a lower bound until the scan covers the source, and a slice that finds nothing says how far it looked and offers to go on. Sorting by a column is a scan too, for a finite source: the best rows are kept and labeled until it completes; an infinite source declines. page and page-size open the table on the row where that page would start.

packages/components/src/notatio-collection-table.ts· draws CollectionTable

Stories

Subsets(4), every subset drawn

Sixteen rows, in the binary (Gray-free) order the kernel unranks. Sort by Length to group by size; filter Length(_) == 2 for the six pairs -- the count goes exact at once, since sixteen rows scan in a millisecond. The Sum column is any expression over the row, not just a head.

source
CollectionTable(
                 Subsets(4),
                 (Columns, "Length, Sum"),
                 (Glyph, "subset"),
                 (PageSize, 10),
               )

notebook cells, the CLI

SymmetricGroup(5), the classical statistics

The 44 derangements of five, picked out of 120 by the filter, each with its Descents number, MajorIndex, Inversions count and Cycles count. Clear the filter to see all 120; sort by Inversions to see that it and MajorIndex are equidistributed but not equal; add Peaks, Excedances or LeftToRightMaxima as further columns.

source
CollectionTable(
                 SymmetricGroup(5),
                 (
                   Columns,
                   "Descents, MajorIndex, Inversions, CycleCount, FixedPoints",
                 ),
                 (Glyph, "permutation"),
                 (Filter, "FixedPoints(_) == 0"),
               )

notebook cells, the CLI

SymmetricGroup(12) -- scrolling without materialising

479,001,600 permutations. The table opens on page one million (page and page-size give its first row) -- At unranks the rows in view directly, and only those. Scroll, or type a row number into the jump field. Sorting a collection this large keeps the best rows over a scan and says how far it has looked; a filter scans twenty thousand rows at a time and offers to continue.

source
CollectionTable(
                 SymmetricGroup(12),
                 (Columns, "Descents, Inversions"),
                 (Glyph, "permutation"),
                 (Page, "1000000"),
                 (PageSize, 10),
               )

notebook cells, the CLI

SymmetricGroup(20)

2,432,902,008,176,640,000 rows -- past Number.MAX_SAFE_INTEGER, so the count is shown as the approximation it is, and the rows are still exact. Row numbers are bigints; type 2432902008176640000 into the jump field for the last permutation. readonly hides the editors.

source
CollectionTable(
                 SymmetricGroup(20),
                 (Columns, "Descents, CycleCount"),
                 (PageSize, 10),
                 (Readonly, True),
               )

notebook cells, the CLI

SymmetricGroup(25), jumped to its last row

15,511,210,043,330,985,984,000,000 permutations. scroll-position is the exact row number, past anything a double holds, so the table opens on the last permutation and the scrollbar is scaled -- wheel and arrow keys move by row.

source
CollectionTable(
                 SymmetricGroup(25),
                 (Columns, "Descents, CycleCount"),
                 (ScrollPosition, "15511210043330985984000000"),
                 (Readonly, True),
               )

notebook cells, the CLI

NonNegativeIntegers, scrolling without end

An infinite set with no At, so the table walks it and keeps the window it has walked. The count is infinite, the scrollbar grows a runway as you reach the end, and a far jump walks forward within a budget rather than freeze. A filter over it, Mod(_, 1000) == 7, is a lower bound that grows as the scan goes; sorting it declines, and says why.

source
CollectionTable(
                 NonNegativeIntegers,
                 (Columns, "Sqrt, Mod(_, 7)"),
                 (Readonly, True),
               )

notebook cells, the CLI

IntegerPartitions(8) as Ferrers diagrams

Partitions unrank in reverse-lexicographic order. The partition statistics come from @enumeratio/statistics, where each is a definition over the part list; filter IsSelfConjugate(_) == 1 for the two self-conjugate partitions of 8, or Length(_) == 3 for the five into three parts.

source
CollectionTable(
                 IntegerPartitions(8),
                 (
                   Columns,
                   "Length, LargestPart, DistinctParts, DurfeeSquare, Crank",
                 ),
                 (Glyph, "partition"),
                 (PageSize, 10),
               )

notebook cells, the CLI

DyckPaths(4) as step words

Fourteen paths (Catalan), as up/down words drawn as mountain ranges. Height, Area, Returns (touches of the axis) and Hills are Dyck-path statistics; sort by Returns to see the Narayana-like split, or filter Returns(_) == 1 for the five primitive paths.

source
CollectionTable(
                 DyckPaths(4),
                 (Columns, "Height, Area, Returns, Hills"),
                 (Glyph, "dyck"),
                 (PageSize, 14),
               )

notebook cells, the CLI

SetPartitions(4), blocks as pills

Fifteen set partitions (Bell). The element is the block list; the glyph converts it to the restricted-growth string the set-partition figure draws. Length counts blocks -- sort by it to walk from one block to four -- and Max(Map(Length, _)) is the largest block.

source
CollectionTable(
                 SetPartitions(4),
                 (Columns, "Length, Max(Map(Length, _))"),
                 (Glyph, "set-partition"),
                 (PageSize, 15),
               )

notebook cells, the CLI

Props

PropTypeDefaultNotes
exprstring""The collection to enumerate, in Epsil: Subsets(4), SymmetricGroup(5).
columnsstring""Statistic columns, comma-separated. A bare head applies to the row (Descents means Descents(_)); anything else is an expression over _.reflects
filterstring""A predicate over the row _, e.g. FixedPoints(_) == 0. Empty for no filter.reflects
sortstring""The column (as written in columns) the rows are ordered by. Empty for index order.reflects
descendingbooleanfalseSort descending rather than ascending.reflects
pageSize
attribute page-size
number20With page: the table opens on the first row of that page.
pagenumber1The page (1-based, of page-size rows) the table opens on.reflects
carrierstring""The carrier its rows inhabit -- the constructor head from @enumeratio/combinatorics, e.g. Permutation. Auto-derived from the first row's own operator, so this is an OVERRIDE, needed only when a story wants a different reading than the collection's own.
glyphstring""Draw each row as a glyph too: permutation, subset, partition, dyck, …
nnumber0Ground-set size for the subset glyph; taken from the collection's first argument when 0.
scanLimit
attribute scan-limit
number0How many source rows a filter or sort scan covers before it pauses and offers to go on.
readonlybooleanfalseHide the editors (expression, columns, filter) and show only the table.
paginationbooleanfalsePages in place of a scroll.
scrollPosition
attribute scroll-position
string""The first row in view (ScrollPosition): digits, so a row past 2^53 stays exact.
maxItems
attribute max-items
number0Rows of a pinned page (MaxItems).

As a web component

Plain custom elements, no framework required: import @enumeratio/frontend for the side effect and write <notatio-collection-table> in any HTML. Attributes are kebab-case and always strings; the props table above names each one's attribute where it differs from its prop.