The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.
flexseq basicsflexseq is a persistent sequence type, with many of the
same features as an R list(), including storing arbitrary
items. All updates return a new object and keep the original
unchanged.
x <- flexseq(1, 2, 3)
x
#> Unnamed flexseq with 3 elements.
#>
#> Elements:
#>
#> [[1]]
#> [1] 1
#>
#> [[2]]
#> [1] 2
#>
#> [[3]]
#> [1] 3
x2 <- as_flexseq(letters[1:5])
x2
#> Unnamed flexseq with 5 elements.
#>
#> Elements:
#>
#> [[1]]
#> [1] "a"
#>
#> [[2]]
#> [1] "b"
#>
#> ... (skipping 1 element)
#>
#> [[4]]
#> [1] "d"
#>
#> [[5]]
#> [1] "e"Flexseqs may be named, but if any are named they must all have unique
non-NULL names. Large named flexseqs are somewhat slower
than unnamed ones; for efficient key/value stores consider using an
ordered_sequence().
x <- flexseq(a = 1, b = 2, c = 3)
x
#> Named flexseq with 3 elements.
#>
#> Elements:
#>
#> $a
#> [1] 1
#>
#> $b
#> [1] 2
#>
#> $c
#> [1] 3
x[c("c", "b")]
#> Named flexseq with 2 elements.
#>
#> Elements:
#>
#> $c
#> [1] 3
#>
#> $b
#> [1] 2
x$b <- NULL # delete b
x
#> Named flexseq with 2 elements.
#>
#> Elements:
#>
#> $a
#> [1] 1
#>
#> $c
#> [1] 3In general indexing and slicing works as it does with lists:
[] returns a sublist indexed by integer (by position),
character vector (by name if named), or logical vector (by inclusion).
Note that these operations are \(O(k\log
n)\) where \(k\) is the length
of the indexing vector.
Flexseqs support pushing new elements onto the front or back of the
sequences, peeking at the front or back (i.e., getting a copy of the
first or last item), and popping from the front or back, which returns
the removed element and a copy of the flexseq input with that item
removed. pop_front() and pop_back() both
return a list with fields $value and
$remaining; peek_back() is the symmetric
counterpart to peek_front().
x <- as_flexseq(4:6)
x <- x |>
push_back(100) |>
push_front(50)
x
#> Unnamed flexseq with 5 elements.
#>
#> Elements:
#>
#> [[1]]
#> [1] 50
#>
#> [[2]]
#> [1] 4
#>
#> ... (skipping 1 element)
#>
#> [[4]]
#> [1] 6
#>
#> [[5]]
#> [1] 100
xpopped <- pop_front(x)
xpopped$value
#> [1] 50
xpopped$remaining
#> Unnamed flexseq with 4 elements.
#>
#> Elements:
#>
#> [[1]]
#> [1] 4
#>
#> [[2]]
#> [1] 5
#>
#> [[3]]
#> [1] 6
#>
#> [[4]]
#> [1] 100Beyond the ends, flexseqs support arbitrary-position persistent
operations. peek_at() is the non-throwing positional read
(compare with [[, which errors when out of bounds);
pop_at() removes an element at a given index and returns
$value/$remaining; insert_at()
inserts before a given index, or at length(x) + 1 to
append.
x <- flexseq("a", "b", "c", "d")
peek_at(x, 10) # NULL, no error
#> NULL
out <- pop_at(x, 2)
out$value
#> [1] "b"
out$remaining
#> Unnamed flexseq with 3 elements.
#>
#> Elements:
#>
#> [[1]]
#> [1] "a"
#>
#> [[2]]
#> [1] "c"
#>
#> [[3]]
#> [1] "d"
insert_at(x, 3, c("x", "y"))
#> Unnamed flexseq with 6 elements.
#>
#> Elements:
#>
#> [[1]]
#> [1] "a"
#>
#> [[2]]
#> [1] "b"
#>
#> ... (skipping 2 elements)
#>
#> [[5]]
#> [1] "c"
#>
#> [[6]]
#> [1] "d"c() concatenates flexseqs, and fapply()
applies a function to each element of one returning the result as a
flexseq, analygous to lapply() for R lists.
x <- as_flexseq(4:6)
x2 <- as_flexseq(8:10)
c(x, x2)
#> Unnamed flexseq with 6 elements.
#>
#> Elements:
#>
#> [[1]]
#> [1] 4
#>
#> [[2]]
#> [1] 5
#>
#> ... (skipping 2 elements)
#>
#> [[5]]
#> [1] 9
#>
#> [[6]]
#> [1] 10
x <- as_flexseq(1:3)
fapply(x, function(el) el * 10)
#> Unnamed flexseq with 3 elements.
#>
#> Elements:
#>
#> [[1]]
#> [1] 10
#>
#> [[2]]
#> [1] 20
#>
#> [[3]]
#> [1] 30merge(x, y) is provided as an alias for
c(x, y) so that merge() works uniformly across
the package’s four structure types. For flexseq,
c() and merge() are equivalent; the
distinction matters for ordered_sequence,
interval_index, and priority_queue, where
merge() performs a proper sorted/priority-aware
combine.
loop() (re-exported from the coro
package) enables for-loop traversal, yielding elements
left-to-right lazily without materializing a list.
x <- flexseq("a", "b", "c", "d")
loop(for (el in x) {
print(el)
})
#> [1] "a"
#> [1] "b"
#> [1] "c"
#> [1] "d"For named flexseqs, loop() yields bare values (matching
peek_front()); use as.list() when you need
names alongside values.
Plain for (el in x) (without loop()) does
not dispatch to the iteration protocol — it walks the
underlying finger-tree storage and yields internal nodes rather than
sequence elements. Always wrap with loop().
Flexseqs convert back to standard R structures with
as.list() (preserves names and list semantics) and
unlist() (atomic vector when possible).
length() returns the element count in O(1), and
str() gives a compact diagnostic display.
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.