slide

A fixed-sized sliding window iteration of size windowSize over a source range by a custom stepSize.

The Source range must be at least a ForwardRange and the windowSize must be greater than zero.

For windowSize = 1 it splits the range into single element groups (aka unflatten) For windowSize = 2 it is similar to zip(source, source.save.dropOne).

slide
(
Flag!"withPartial" f = Yes.withPartial
Source
)
(
Source source
,
size_t windowSize
,
size_t stepSize = 1
)
if (
isForwardRange!Source
)

Parameters

f

Whether the last element has fewer elements than windowSize it should be be ignored (No.withPartial) or added (Yes.withPartial)

source Source

Range from which the slide will be selected

windowSize size_t

Sliding window size

stepSize size_t

Steps between the windows (by default 1)

Return Value

Type: auto

Range of all sliding windows with propagated bi-directionality, forwarding, random access, and slicing.

Note: To avoid performance overhead, bi-directionality is only available when std.range.primitives.hasSlicing and std.range.primitives.hasLength are true.

Examples

Iterate over ranges with windows

import std.algorithm.comparison : equal;

assert([0, 1, 2, 3].slide(2).equal!equal(
    [[0, 1], [1, 2], [2, 3]]
));

assert(5.iota.slide(3).equal!equal(
    [[0, 1, 2], [1, 2, 3], [2, 3, 4]]
));

set a custom stepsize (default 1)

import std.algorithm.comparison : equal;

assert(6.iota.slide(1, 2).equal!equal(
    [[0], [2], [4]]
));

assert(6.iota.slide(2, 4).equal!equal(
    [[0, 1], [4, 5]]
));

assert(iota(7).slide(2, 2).equal!equal(
    [[0, 1], [2, 3], [4, 5], [6]]
));

assert(iota(12).slide(2, 4).equal!equal(
    [[0, 1], [4, 5], [8, 9]]
));

Allow the last slide to have fewer elements than windowSize

import std.algorithm.comparison : equal;

assert(3.iota.slide!(No.withPartial)(4).empty);
assert(3.iota.slide!(Yes.withPartial)(4).equal!equal(
    [[0, 1, 2]]
));

Count all the possible substrings of length 2

import std.algorithm.iteration : each;

int[dstring] d;
"AGAGA"d.slide!(Yes.withPartial)(2).each!(a => d[a]++);
assert(d == ["AG"d: 2, "GA"d: 2]);

withPartial only has an effect if last element in the range doesn't have the full size

import std.algorithm.comparison : equal;

assert(5.iota.slide!(Yes.withPartial)(3, 4).equal!equal([[0, 1, 2], [4]]));
assert(6.iota.slide!(Yes.withPartial)(3, 4).equal!equal([[0, 1, 2], [4, 5]]));
assert(7.iota.slide!(Yes.withPartial)(3, 4).equal!equal([[0, 1, 2], [4, 5, 6]]));

assert(5.iota.slide!(No.withPartial)(3, 4).equal!equal([[0, 1, 2]]));
assert(6.iota.slide!(No.withPartial)(3, 4).equal!equal([[0, 1, 2]]));
assert(7.iota.slide!(No.withPartial)(3, 4).equal!equal([[0, 1, 2], [4, 5, 6]]));

See Also

Meta