英語版
このページの英語版を見る

std.range

このモジュールでは、範囲の概念を定義する。範囲は、配列、リスト、またはシーケンシャルアクセスを伴うその他の概念を一般化する。 この抽象化により、 同じアルゴリズムセット(参照 std.algorithmさまざまな異なる具体的な型で同じアルゴリズムセットを使用できるようになる。 例えば、 線形探索アルゴリズムは、 std.algorithm.searching.find 配列だけでなく、連結リスト、入力ファイル、 受信ネットワークデータなどにも

ガイド 範囲の理解を深めるための記事は数多く公開されている。

部分モジュール このモジュールには2つの部分モジュールがある。 xml-ph-0000@deepl.internal

部分モジュール このモジュールには2つの部分モジュールがある。

std.range.primitivesサブモジュールは、 基本的な範囲の機能を提供する。これは、与えられたオブジェクトが範囲であるかどうか、どのような種類の範囲であるか、 そしていくつかの一般的な範囲操作を 提供する。
std.range.interfacesサブモジュールは、 実行時多相性により、オブジェクトベースのインターフェイスで範囲を操作する。
このモジュールの残りの部分では、範囲の作成と合成のための豊富なテンプレートを提供し、 既存の範囲から新しい範囲を構築できるようにする。
chain 複数の範囲を1つの範囲に連結する。
choose 実行時に、ブール値の条件に基づいて2つの範囲のいずれかを選択する。
chooseAmong インデックスに基づいて、実行時に複数の範囲から1つを選択する。
chunks 元のレンジから固定サイズのチャンクを返すレンジを作成する 。
cycle 与えられた順方向の範囲を無限に繰り返す無限の範囲を作成する。 循環バッファの実装に便利。
drop 指定した範囲から最初の n 個の要素を削除した結果となる範囲を作成する 。
dropBack 与えられた範囲から最後の n 個の要素を破棄した結果の 範囲を作成する。
dropExactly 与えられた範囲の最初の要素から正確にn 個を削除した結果の 範囲を作成する。
dropBackExactly 指定した範囲の最後の要素から正確にn 個の要素を削除した結果となる範囲を作成する。
dropOne 指定した範囲の最初の要素を削除した結果の 範囲を作成する。
dropBackOne 指定した範囲から最後の要素を削除した結果の 範囲を作成する。
enumerate 添え字変数付きの範囲を反復する。
evenChunks 元の範囲からほぼ同じ長さのチャンクをいくつか返す範囲を作成する 。
frontTransversal 与えられた範囲の最初の要素を順に処理する範囲を作成する 。
generate 指定した関数を順次呼び出すことで、範囲を作成する。これにより、 単一のデリゲートとして範囲を作成することができる。
indexed あたかも、与えられた範囲の要素が 与えられたインデックスの範囲に従って並べ替えられたかのように、与えられた範囲のビューを提供する範囲を作成する。
iota 開始点と終了点の間の数値で構成される範囲を 作成し、指定された間隔で間を空ける。
lockstep foreachループで使用するために、n 個の範囲を順番に繰り返す。zip と同様だが、lockstepforeach ループ専用に設計されている。
nullSink 受信したデータを破棄する出力範囲。
only 指定された引数を繰り返し処理する範囲を作成する。
padLeft 指定した要素を範囲の先頭に追加することで、範囲を指定した長さに揃える 。範囲の長さが既知の場合は、遅延処理される。
padRight 与えられた要素を範囲の後ろに追加することで、範囲を指定の長さに遅延パディングする。
radial ランダムアクセス可能な範囲と開始点が与えられた場合、 開始点から見て次の左の要素と次の右の要素を交互に返す範囲を作成する 。
recurrence 数学的帰納法によって定義された値を持つ順方向の範囲を作成する 。
refRange 参照渡しで範囲を渡す。元の範囲と RefRange は 常にまったく同じ要素を持つ。 どちらか一方に対して実行された操作は、もう一方にも影響する。
repeat 単一の要素をn 回繰り返す範囲、またはその要素を無限に繰り返す無限の範囲を作成する 。
retro 双方向の範囲を後ろ向きに反復する。
roundRobin n個の範囲が与えられた場合、新しい範囲を作成し、 各範囲の最初のn個の要素を順番に返し、次に各範囲の2番目の要素を返し、 以下同様に、ラウンドロビン方式で返す。
sequence recurrence と同様だが、ランダムアクセス可能な範囲が作成される点が異なる。
slide 元の範囲に対して固定サイズのスライディングウィンドウを返す範囲を作成する。 チャンクとは異なり、 一度に設定可能な数のアイテムを順次進めるもので、 一度にチャンクを1つずつ進めるものではない。
stride 範囲をステップn で繰り返す。
tail 与えられた範囲の末尾からn 個以内の範囲を返す 。
take 与えられた範囲の最初の n 個までの要素のみで構成されるサブ範囲を作成する 。
takeExactly take と同様だが、与えられた範囲には実際にn個の要素が存在すると仮定する 。したがって、length プロパティも定義される。
takeNone 指定された範囲の最初の要素から最後の要素までをランダムアクセス可能な範囲として作成する。
takeOne 指定された範囲の最初の要素のみで構成されるランダムアクセス範囲を作成する 。
tee 与えられた範囲をラップする範囲を作成し、 その要素に沿って進むとともに、各要素で指定された関数を呼び出す。
transposed 範囲の並び替えを行う。
transversal 与えられたランダムアクセス範囲のn 番目の要素を順に繰り返す範囲を作成する 。
zip n個の範囲が与えられた場合、順次、 最初の要素のタプル、2番目の要素のタプル、 など を返す範囲を作成する。

ソート 要素がソートされた範囲は、特定の操作においてより高い効率性を実現する。 このために、 assumeSorted関数を使用して、 事前にソートされた範囲から SortedRange事前にソートされた範囲から構築する。 std.algorithm.sorting.sort関数は、 を返すこともできる SortedRangeSortedRangeオブジェクトは、 範囲がソートされていることを利用した追加の

Authors:
Andrei Alexandrescu, David Simcha, Jonathan M Davis, and Jack Stouffer. Credit for some of the ideas in building this module goes to Leonardo Maffi.
auto retro(Range)(Range r)
if (isBidirectionalRange!(Unqual!Range));
双方向の範囲を後ろ向きに反復する。元の範囲は、source プロパティを使用してアクセスできる。同じ範囲にretroを2回適用すると、 元の範囲が得られる。
Parameters:
Range r 双方向の範囲を逆方向に反復する
Returns: 双方向範囲の長さ
双方向範囲の長さも r長さも提供する。または、 rランダムアクセス範囲である場合、戻り値もランダムアクセスとなる。
See Also:
std.algorithm.mutation.reverseソース範囲を直接変更する。
length直接
Examples:
import std.algorithm.comparison : equal;
int[5] a = [ 1, 2, 3, 4, 5 ];
int[5] b = [ 5, 4, 3, 2, 1 ];
assert(equal(retro(a[]), b[]));
assert(retro(a[]).source is a[]);
assert(retro(retro(a[])) is a[]);
auto stride(Range)(Range r, size_t n)
if (isInputRange!(Unqual!Range));
範囲を反復する rストライドで n。 範囲がランダムアクセス可能な範囲である場合は、 その範囲にインデックスを指定して移動する。 そうでない場合は、popFront を連続して呼び出すことで移動する。 同じ範囲に対してストライドを2回適用すると、 ステップが 2回の適用結果となる。 0であることはエラーである n0になることはあり得ません。
Parameters:
Range r 入力範囲を飛び越える
size_t n スキップする要素数
Returns: 最小値として、入力範囲。結果として得られる範囲は、 基礎となる範囲のレンジプリミティブを採用する。
少なくとも、入力範囲。結果として得られる範囲は、 xml-ph-0000@deepl.internal である限り、 std.range.primitives.hasLengthtrue である限り、
xml-ph-0000@deepl.internalxml-ph-0000@deepl.internal
Examples:
import std.algorithm.comparison : equal;

int[] a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ];
assert(equal(stride(a, 3), [ 1, 4, 7, 10 ][]));
writeln(stride(stride(a, 2), 3)); // stride(a, 6)
auto chain(Ranges...)(Ranges rs)
if (Ranges.length > 0 && allSatisfy!(isInputRange, staticMap!(Unqual, Ranges)) && !is(CommonType!(staticMap!(ElementType, staticMap!(Unqual, Ranges))) == void));
複数の範囲を順番にまたがる。この関数は、 chain任意の 数の範囲を受け取り、Chain!(R1, R2,...) オブジェクトを返す。 範囲は異なっていてもよいが、同じ要素型でなければならない。 結果は、frontpopFrontempty のプリミティブを提供する範囲となる。すべての入力範囲がランダムアクセスとlength を提供する場合、Chain もそれらを提供する。
結果として得られる範囲のランダムアクセスを繰り返すと、パフォーマンスが低下する可能性が高いことに注意 すること。これは、チェーン内の範囲の長さを ランダムアクセス操作ごとに合計する必要があるためである。最初の残りの範囲の要素へのランダムアクセスは 依然として効率的である。
Chain または に1つの範囲のみが提供される場合、 chainChain 型は、その範囲の型に直接エイリアス化することで、その場から消える。
Parameters:
Ranges rs 入力範囲を連結する
Returns: 最小値の入力範囲。すべての範囲が最小値の場合、
最小値の入力範囲。 すべての範囲が rs範囲プリミティブを提供している場合、返される範囲にもその範囲プリミティブが提供される 。 range primitive範囲プリミティブ
See Also:
only値を範囲に連結する
Examples:
import std.algorithm.comparison : equal;

int[] arr1 = [ 1, 2, 3, 4 ];
int[] arr2 = [ 5, 6 ];
int[] arr3 = [ 7 ];
auto s = chain(arr1, arr2, arr3);
writeln(s.length); // 7
writeln(s[5]); // 6
assert(equal(s, [1, 2, 3, 4, 5, 6, 7][]));
Examples: 範囲のプリミティブは、すべての範囲がそれらを提供している場合、
範囲のプリミティブは、 すべての範囲がそれらを提供している場合、
import std.algorithm.comparison : equal;
import std.algorithm.sorting : sort;

int[] arr1 = [5, 2, 8];
int[] arr2 = [3, 7, 9];
int[] arr3 = [1, 4, 6];

// すべての配列を対象としたインプレースソート
auto s = arr1.chain(arr2, arr3).sort;

assert(s.equal([1, 2, 3, 4, 5, 6, 7, 8, 9]));
assert(arr1.equal([1, 2, 3]));
assert(arr2.equal([4, 5, 6]));
assert(arr3.equal([7, 8, 9]));
Examples: D言語の安全な型変換により、異なる文字範囲を連結すると、xml-ph-0000@deepl.internalという範囲が生成される。xml-ph-0001@deepl.internal
D言語の安全な型昇格により、異なる文字範囲を連結すると、uint という文字範囲が生成される。
必要な型を取得するには、byChar 、byWcharbyDcharを範囲に対して使用する。
import std.utf : byChar, byCodeUnit;

auto s1 = "string one";
auto s2 = "string two";
// s1とs2の先頭は、自動デコードのためのdcharである
static assert(is(typeof(s1.front) == dchar) && is(typeof(s2.front) == dchar));

auto r1 = s1.chain(s2);
// 同じ文字型の範囲のチェーンは、同じ型を与える
static assert(is(typeof(r1.front) == dchar));

auto s3 = "string three".byCodeUnit;
static assert(is(typeof(s3.front) == immutable char));
auto r2 = s1.chain(s3);
// 文字型の混合範囲を連結すると、`dchar`になる
static assert(is(typeof(r2.front) == dchar));

// 文字の範囲に対してbyCharを使用して、正しくUTF-8に変換する
auto r3 = s1.byChar.chain(s3);
static assert(is(typeof(r3.front) == immutable char));
auto choose(R1, R2)(bool condition, return scope R1 r1, return scope R2 r2)
if (isInputRange!(Unqual!R1) && isInputRange!(Unqual!R2) && !is(CommonType!(ElementType!(Unqual!R1), ElementType!(Unqual!R2)) == void));
実行時に、ブール値の条件に応じて2つの範囲のいずれかを選択する。
範囲は異なる可能性があるが、互換性のある要素型でなければならない(すなわち、 2つの要素型に対してCommonType が存在しなければならない)。結果として得られる範囲は、 2つのうちで最も機能が弱いものである(例えば、R1 がランダムアクセス可能な範囲であり、R2 が前方範囲である場合、ForwardRange となる)。
Parameters:
bool condition どの範囲を選択するか: r1true の場合は、 r2そうでなければ、
R1 r1 「真」の範囲
R2 r2 「偽」の範囲
Returns: xml-ph-0000@deepl.internalとxml-ph-0001@deepl.internalに依存する範囲の種類。
R1R2 に依存する範囲の型。
xml-ph-0000@deepl.internalxml-ph-0000@deepl.internal
Examples:
import std.algorithm.comparison : equal;
import std.algorithm.iteration : filter, map;

auto data1 = only(1, 2, 3, 4).filter!(a => a != 3);
auto data2 = only(5, 6, 7, 8).map!(a => a + 1);

// choose()は主に、実行時に異なる型の2つの範囲から
// 1つを選択する必要がある場合に役立つ。
static assert(!is(typeof(data1) == typeof(data2)));

auto chooseRange(bool pickFirst)
{
    // 返される範囲は、型エラーが発生することなく、
    // どちらの範囲も返したり保存したりするために使用できる共通のラッパータイプである。
    return choose(pickFirst, data1, data2);

    // 単に、choose()を使用せずに選択した範囲を返しても動作しない。なぜなら、
    // types.map()とfilter()は異なる型を返すからだ。
    //return pickFirst ? data1 : data2; // コンパイルされない
}

auto result = chooseRange(true);
assert(result.equal(only(1, 2, 4)));

result = chooseRange(false);
assert(result.equal(only(6, 7, 8, 9)));
auto chooseAmong(Ranges...)(size_t index, return scope Ranges rs)
if (Ranges.length >= 2 && allSatisfy!(isInputRange, staticMap!(Unqual, Ranges)) && !is(CommonType!(staticMap!(ElementType, Ranges)) == void));
実行時に複数の範囲から1つを選択する。
範囲は異なっていてもよいが、互換性のある要素型でなければならない。 結果として得られるのは、Ranges の最も弱い機能を提供する範囲である。
Parameters: どの範囲を選択するかは、範囲の数よりも少ない数でなければならない。
size_t index どの範囲を選択するかは、範囲の数より少ない数でなければならない
Ranges rs 2つ以上の範囲
Returns: インデックス付きの範囲。rs が1つの範囲のみで構成されている場合、戻り値の型はその範囲の型のエイリアスとなる。
インデックス付きの範囲。rs が1つの範囲のみで構成されている場合、戻り値の型は その範囲の型のエイリアスとなる。
rangerange
Examples:
auto test()
{
    import std.algorithm.comparison : equal;

    int[4] sarr1 = [1, 2, 3, 4];
    int[2] sarr2 = [5, 6];
    int[1] sarr3 = [7];
    auto arr1 = sarr1[];
    auto arr2 = sarr2[];
    auto arr3 = sarr3[];

    {
        auto s = chooseAmong(0, arr1, arr2, arr3);
        auto t = s.save;
        writeln(s.length); // 4
        writeln(s[2]); // 3
        s.popFront();
        assert(equal(t, only(1, 2, 3, 4)));
    }
    {
        auto s = chooseAmong(1, arr1, arr2, arr3);
        writeln(s.length); // 2
        s.front = 8;
        assert(equal(s, only(8, 6)));
    }
    {
        auto s = chooseAmong(1, arr1, arr2, arr3);
        writeln(s.length); // 2
        s[1] = 9;
        assert(equal(s, only(8, 9)));
    }
    {
        auto s = chooseAmong(1, arr2, arr1, arr3)[1 .. 3];
        writeln(s.length); // 2
        assert(equal(s, only(2, 3)));
    }
    {
        auto s = chooseAmong(0, arr1, arr2, arr3);
        writeln(s.length); // 4
        writeln(s.back); // 4
        s.popBack();
        s.back = 5;
        assert(equal(s, only(1, 2, 5)));
        s.back = 3;
        assert(equal(s, only(1, 2, 3)));
    }
    {
        uint[5] foo = [1, 2, 3, 4, 5];
        uint[5] bar = [6, 7, 8, 9, 10];
        auto c = chooseAmong(1, foo[], bar[]);
        writeln(c[3]); // 9
        c[3] = 42;
        writeln(c[3]); // 42
        writeln(c.moveFront()); // 6
        writeln(c.moveBack()); // 10
        writeln(c.moveAt(4)); // 10
    }
    {
        import std.range : cycle;
        auto s = chooseAmong(0, cycle(arr2), cycle(arr3));
        assert(isInfinite!(typeof(s)));
        assert(!s.empty);
        writeln(s[100]); // 8
        writeln(s[101]); // 9
        assert(s[0 .. 3].equal(only(8, 9, 8)));
    }
    return 0;
}
// 実行時に動作する
auto a = test();
// そしてコンパイル時も
static b = test();
auto roundRobin(Rs...)(Rs rs)
if (Rs.length > 1 && allSatisfy!(isInputRange, staticMap!(Unqual, Rs)));
roundRobin(r1, r2, r3) r1.front 、次に 、 次に となり、その後、それぞれから要素を1つ取り除き、 再び から繰り返す。例えば、2つの範囲が関与している場合、 2つの範囲から交互に要素が生成される。r2.front r3.front r1roundRobin すべての範囲を消費し終えると停止する(早く終わったものはスキップする )。
to stop停止
Examples:
import std.algorithm.comparison : equal;

int[] a = [ 1, 2, 3 ];
int[] b = [ 10, 20, 30, 40 ];
auto r = roundRobin(a, b);
assert(equal(r, [ 1, 10, 2, 20, 3, 30, 40 ]));
Examples:
roundRobin を使用すると、 範囲内の各要素の間に要素を挿入する「インターリーブ」機能を作成できる。
import std.algorithm.comparison : equal;

auto interleave(R, E)(R range, E element)
if ((isInputRange!R && hasLength!R) || isForwardRange!R)
{
    static if (hasLength!R)
        immutable len = range.length;
    else
        immutable len = range.save.walkLength;

    return roundRobin(
        range,
        element.repeat(len - 1)
    );
}

assert(interleave([1, 2, 3], 0).equal([1, 0, 2, 0, 3]));
roundRobinroundRobin
auto radial(Range, I)(Range r, I startingIndex)
if (isRandomAccessRange!(Unqual!Range) && hasLength!(Unqual!Range) && hasSlicing!(Unqual!Range) && isIntegral!I);

auto radial(R)(R r)
if (isRandomAccessRange!(Unqual!R) && hasLength!(Unqual!R) && hasSlicing!(Unqual!R));
指定したポイントから開始し、 そのポイントから左右に段階的に拡張するランダムアクセス範囲を反復する。初期ポイントが指定されていない場合、 反復は範囲の中央から開始する。反復は範囲全体にわたって行われる。
startingIndex0 の場合、範囲は順番に完全に反復処理される。 また、 r.length指定されている場合は、
Parameters:
Range r 長さを持つランダムアクセス可能な範囲と、
I startingIndex インデックスをスライスして反復を開始する
Returns: 前方の順方向の範囲
前方の順方向の範囲の長さ
length長さ
Examples:
import std.algorithm.comparison : equal;
int[] a = [ 1, 2, 3, 4, 5 ];
assert(equal(radial(a), [ 3, 4, 2, 5, 1 ]));
a = [ 1, 2, 3, 4 ];
assert(equal(radial(a), [ 2, 3, 1, 4 ]));

// 最初に左端が到達した場合、右側の残りの要素は
// 順番に連結される:
a = [ 0, 1, 2, 3, 4, 5 ];
assert(equal(radial(a, 1), [ 1, 2, 0, 3, 4, 5 ]));

// 右端に最初に到達した場合、左側の残りの要素は
// 逆順で連結される:
assert(equal(radial(a, 4), [ 4, 5, 3, 2, 1, 0 ]));
Take!R take(R)(R input, size_t n)
if (isInputRange!(Unqual!R));

struct Take(Range) if (isInputRange!(Unqual!Range) && !(!isInfinite!(Unqual!Range) && hasSlicing!(Unqual!Range) || is(Range T == Take!T)));

template Take(R) if (isInputRange!(Unqual!R) && (!isInfinite!(Unqual!R) && hasSlicing!(Unqual!R) || is(R T == Take!T)))
遅延処理により、最大 n範囲の要素だけを取得します。これは 特に無限の範囲を使用する場合に便利です。
takeExactlytake要素が存在する必要はありません。 n要素以上が存在する必要はありません。 input。そのため、 length 情報が結果に適用されるのは、 input長さ情報も 持っていない限り、
Parameters:
R input 入力範囲を 反復処理して、最大 n要素数
size_t n 要素の数だけ繰り返す
Returns: 少なくとも、入力範囲。その範囲がランダムアクセス可能であり、xml-ph-0000@deepl.internal
少なくとも、入力範囲。その範囲がランダムアクセスを提供し、length が 提供する場合は、 takeそれらも提供する。
xml-ph-0000@deepl.internalxml-ph-0000@deepl.internal
Examples:
import std.algorithm.comparison : equal;

int[] arr1 = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
auto s = take(arr1, 5);
writeln(s.length); // 5
writeln(s[4]); // 5
assert(equal(s, [ 1, 2, 3, 4, 5 ][]));
Examples:
範囲が要素の前に終了する場合は、 n要素がなくなる前に、 take単にその範囲全体を返します ( takeExactly、範囲が早期に終了した場合にアサーションエラーが発生するのとは異なり、
import std.algorithm.comparison : equal;

int[] arr2 = [ 1, 2, 3 ];
auto t = take(arr2, 5);
writeln(t.length); // 3
assert(equal(t, [ 1, 2, 3 ]));
assertion failureアサーションエラー
auto takeExactly(R)(R range, size_t n)
if (isInputRange!R);
と同様だが、 takeが、 range少なくともn 個の要素を持つと想定します。したがって、takeExactly(range, n)の結果は 常にlength プロパティを定義し(そして、それを初期化します nrangelength を定義していない場合でも、
結果は takeExactly、元の範囲が xml-ph-0000@deepl.internal を定義している場合、または無限である場合の take元の範囲がlength を定義している場合、または無限である場合
とは異なり、 take、しかし、要素数が1未満のレンジを渡すことは違法であるntakeExactly。これはアサーションエラーの原因となる。
internalinternal
Examples:
import std.algorithm.comparison : equal;

auto a = [ 1, 2, 3, 4, 5 ];

auto b = takeExactly(a, 3);
assert(equal(b, [1, 2, 3]));
static assert(is(typeof(b.length) == size_t));
writeln(b.length); // 3
writeln(b.front); // 1
writeln(b.back); // 3
最大1つの要素を持つ範囲を返します。例えば、xml-ph-0000@deepl.internal は整数xml-ph-0001@deepl.internal からなる範囲を返します。xml-phを呼び出す
auto takeOne(R)(R source)
if (isInputRange!R);
最大でも1つの要素を持つ範囲を返します。例えば、takeOne([42, 43, 44]) は整数42 からなる範囲を返します。popFront() をその範囲から呼び出すと、その範囲は空になります。
事実上、 takeOne(r)take(r, 1) とほぼ同義ですが、 特定のインターフェイスでは、その範囲が最大でも1つの要素しか持たないことを静的に知っておくことが重要です。
によって返される型は takeOneランダムアクセス可能な長さを持つ範囲である。R の機能に関係なく、順方向の範囲であれば、 ( とのもう一つの違いである takeOnetake。 (D R) が入力範囲であっても順方向の範囲でない場合、戻り値の型は 保存以外のすべてのランダムアクセス機能を持つ入力範囲となる。
range範囲
Examples:
auto s = takeOne([42, 43, 44]);
static assert(isRandomAccessRange!(typeof(s)));
writeln(s.length); // 1
assert(!s.empty);
writeln(s.front); // 42
s.front = 43;
writeln(s.front); // 43
writeln(s.back); // 43
writeln(s[0]); // 43
s.popFront();
writeln(s.length); // 0
assert(s.empty);
range範囲
auto takeNone(R)()
if (isInputRange!R);
静的に空であることが分かっており、length であることが保証され、R の機能に関係なくランダムアクセスが可能である 空の範囲を返す。
xml-ph-0001@deepl.internalxml-ph-0001@deepl.internal
Examples:
auto range = takeNone!(int[])();
writeln(range.length); // 0
assert(range.empty);
auto takeNone(R)(R range)
if (isInputRange!R);
Ο (1) で指定された範囲から空の範囲を作成する。可能であれば、 同じ範囲型を返す。不可能であれば、takeExactly(range, 0) を返す。
emailemail
Examples:
import std.algorithm.iteration : filter;
assert(takeNone([42, 27, 19]).empty);
assert(takeNone("dlang.org").empty);
assert(takeNone(filter!"true"([42, 27, 19])).empty);
auto tail(Range)(Range range, size_t n)
if (isInputRange!Range && !isInfinite!Range && (hasLength!Range || isForwardRange!Range));
末尾から_n 要素以内の範囲を先頭に戻す range
Unixのtailユーティリティに相当する範囲として意図されている。 長さが range_n 以下である場合、 rangeそのまま返される。
スライスをサポートし、長さを持つ範囲については、Ο(1)ステップで完了する。 それ以外のすべての範囲については、Ο(range.length)時間で完了する。
OmicronOmicron
Parameters:
Range range 範囲の末尾を取得する
size_t n テールに含める要素の最大数
Returns: テールを返す。
末尾を返す。 range長さ情報を付加した
tailtail
Examples:
// tail -c n
writeln([1, 2, 3].tail(1)); // [3]
writeln([1, 2, 3].tail(2)); // [2, 3]
writeln([1, 2, 3].tail(3)); // [1, 2, 3]
writeln([1, 2, 3].tail(4)); // [1, 2, 3]
writeln([1, 2, 3].tail(0).length); // 0

// tail --lines=n
import std.algorithm.comparison : equal;
import std.algorithm.iteration : joiner;
import std.exception : assumeWontThrow;
import std.string : lineSplitter;
assert("one\ntwo\nthree"
    .lineSplitter
    .tail(2)
    .joiner("\n")
    .equal("two\nthree")
    .assumeWontThrow);
convenience function便利機能
R drop(R)(R range, size_t n)
if (isInputRange!R);

R dropBack(R)(R range, size_t n)
if (isBidirectionalRange!R);
呼び出しと返却を行う便利な関数 std.range.primitives.popFrontN(range, n)rangedropこれにより、要素を範囲から取り出して、 それを単一の式内で別の関数に渡すことが容易になる。popFrontN では複数の文が必要になるが、
dropBack同じ機能を提供するが、代わりに呼び出す std.range.primitives.popBackN(range, n)

注釈dropdropBack要素のみにポップアップ表示されますが n要素のみにポップアップ表示され、最初に範囲が空の場合は停止する。 他の言語では、これはskip と呼ばれることもある。

Parameters:
R range ドロップする入力範囲
size_t n 削除する要素の数
Returns:
range最大で n要素が削除される
Examples:
import std.algorithm.comparison : equal;

writeln([0, 2, 1, 5, 0, 3].drop(3)); // [5, 0, 3]
writeln("hello world".drop(6)); // "world"
assert("hello world".drop(50).empty);
assert("hello world".take(6).drop(3).equal("lo "));
element要素
Examples:
import std.algorithm.comparison : equal;

writeln([0, 2, 1, 5, 0, 3].dropBack(3)); // [0, 2, 1]
writeln("hello world".dropBack(6)); // "hello"
assert("hello world".dropBack(50).empty);
assert("hello world".drop(4).dropBack(4).equal("o w"));
R dropExactly(R)(R range, size_t n)
if (isInputRange!R);

R dropBackExactly(R)(R range, size_t n)
if (isBidirectionalRange!R);
dropdropBack だが、彼らは range.popFrontExactly(n)range.popBackExactly(n) 代わりに

注釈 drop とは異なり、 dropExactly範囲には少なくとも 要素が含まれていると仮定する n。これにより、 dropExactly drop よりも高速になりますが、 range少なくとも 1つの要素が含まれていない n要素が含まれていない場合、空の範囲に対してpopFrontを呼び出そうと試みる ことになり、これは未定義の動作となります。そのため、popFrontExactly は、 range少なくとも n

Parameters:
R range 入力範囲から削除する
size_t n 削除する要素の数
Returns:
range要素が削除された n要素が削除された
withだ
Examples:
import std.algorithm.comparison : equal;
import std.algorithm.iteration : filterBidirectional;

auto a = [1, 2, 3];
writeln(a.dropExactly(2)); // [3]
writeln(a.dropBackExactly(2)); // [1]

string s = "日本語";
writeln(s.dropExactly(2)); // "語"
writeln(s.dropBackExactly(2)); // "日"

auto bd = filterBidirectional!"true"([1, 2, 3]);
assert(bd.dropExactly(2).equal([3]));
assert(bd.dropBackExactly(2).equal([1]));
、 convenience function便利機能
R dropOne(R)(R range)
if (isInputRange!R);

R dropBackOne(R)(R range)
if (isBidirectionalRange!R);
呼び出しと返却を行う便利関数 range.popFront()戻り値を返す rangedropOne これにより、要素を範囲から取り出して、 それを単一の式内で別の関数に渡すことが容易になる。 一方、popFront では複数の文が必要になる。
dropBackOne同じ機能を提供するが、代わりに range.popBack()
to provide提供する
Examples:
import std.algorithm.comparison : equal;
import std.algorithm.iteration : filterBidirectional;
import std.container.dlist : DList;

auto dl = DList!int(9, 1, 2, 3, 9);
assert(dl[].dropOne().dropBackOne().equal([1, 2, 3]));

auto a = [1, 2, 3];
writeln(a.dropOne()); // [2, 3]
writeln(a.dropBackOne()); // [1, 2]

string s = "日本語";
import std.exception : assumeWontThrow;
assert(assumeWontThrow(s.dropOne() == "本語"));
assert(assumeWontThrow(s.dropBackOne() == "日本"));

auto bd = filterBidirectional!"true"([1, 2, 3]);
assert(bd.dropOne().equal([2, 3]));
assert(bd.dropBackOne().equal([1, 2]));
range範囲
struct Repeat(T);

Repeat!T repeat(T)(T value);

Take!(Repeat!T) repeat(T)(T value, size_t n);
1つの値を繰り返す範囲を作成する。
Parameters: 繰り返す値を
T value 繰り返す値
size_t n 繰り返す回数 value
Returns:
n定義されていない場合、スライスによる無限のランダムアクセス範囲。
n定義されている場合は、スライス機能付きのランダムアクセス範囲。
Examples:
import std.algorithm.comparison : equal;

assert(5.repeat().take(4).equal([5, 5, 5, 5]));
random access rangeランダムアクセス範囲
Examples:
import std.algorithm.comparison : equal;

assert(5.repeat(4).equal([5, 5, 5, 5]));
inout @property inout(T) front();

inout @property inout(T) back();

enum bool empty;

void popFront();

void popBack();

inout @property auto save();

inout inout(T) opIndex(size_t);

auto opSlice(size_t i, size_t j);

enum auto opDollar;

inout auto opSlice(size_t, DollarToken);
範囲のプリミティブ
auto generate(Fun)(Fun fun)
if (isCallable!fun);

auto generate(alias fun)()
if (isCallable!fun);
与えられたコール可能 (std.traits.isCallable) fun、範囲として作成する。 その先頭は、連続した呼び出しによって定義される fun()。 これは、グローバルな副作用を持つ関数(ランダム関数)を呼び出す場合や、front/popFront/empty の構造全体ではなく、単一のデリゲートとして表現される範囲を作成する場合に特に役立つ。funテンプレートエイリアスパラメータ(既存の 関数、デリゲート、static opCall を定義する構造体型)または 実行時値引数(デリゲート、関数オブジェクト)を渡すことができる。 結果の範囲は InputRange をモデル化する (std.range.primitives.isInputRange。 結果の範囲は、 fun()生成時に呼び出され、popFront へのすべての呼び出しに対して、front が呼び出された場合はキャッシュされた値が返される。
Returns:
inputRange では、各要素が fun への別の呼び出しを表している。
Examples:
import std.algorithm.comparison : equal;
import std.algorithm.iteration : map;

int i = 1;
auto powersOfTwo = generate!(() => i *= 2)().take(10);
assert(equal(powersOfTwo, iota(1, 11).map!"2^^a"()));
funfun
Examples:
import std.algorithm.comparison : equal;

//実行時デリゲートを返す
auto infiniteIota(T)(T low, T high)
{
    T i = high;
    return (){if (i == high) i = low; return i++;};
}
//範囲として適応された。
assert(equal(generate(infiniteIota(1, 4)).take(10), [1, 2, 3, 1, 2, 3, 1, 2, 3, 1]));
funfun
Examples:
import std.format : format;
import std.random : uniform;

auto r = generate!(() => uniform(0, 6)).take(10);
format("%(%s %)", r);
与えられた前方の範囲を無限に繰り返す。元の範囲が 無限である場合(その場合、
struct Cycle(R) if (isForwardRange!R && !isInfinite!R);

template Cycle(R) if (isInfinite!R)

struct Cycle(R) if (isStaticArray!R);

auto cycle(R)(R input)
if (isInputRange!R);

Cycle!R cycle(R)(R input, size_t index = 0)
if (isRandomAccessRange!R && !isInfinite!R);

@system Cycle!R cycle(R)(ref R input, size_t index = 0)
if (isStaticArray!R);
与えられた前方の範囲を無限に繰り返す。元の範囲が 無限である場合( Cycle同一アプリケーションとなる)場合、Cycleそれを検知し、自身を範囲型にエイリアスします。 これは順方向の範囲以外でも機能します。 元の範囲がランダムアクセス可能であれば、 Cycleランダムアクセスを提供し、 また、初期位置を受け取るコンストラクタも提供するindexCycle、パフォーマンス上の理由から、範囲に加えて静的配列にも対応している。

注釈 入力範囲は空であってはならない。

ヒント これは、単純な循環バッファを実装する素晴らしい方法である。

circular buffer循環バッファ
Examples:
import std.algorithm.comparison : equal;
import std.range : cycle, take;

// ここでは、[1, 2]から無限循環数列を作成し
// (つまり、[1, 2, 1, 2, 1, 2など]を取得する)、
// この数列から5つの要素をを取得して(つまり、[1, 2, 1, 2, 1]となる)、
// それらを等価であると期待される値と比較する。
assert(cycle([1, 2]).take(5).equal([ 1, 2, 1, 2, 1 ]));
this(R input, size_t index = 0);

@property ref auto front();

const @property ref auto front();

@property void front(ElementType!R val);

enum bool empty;

void popFront();

ref auto opIndex(size_t n);

const ref auto opIndex(size_t n);

void opIndexAssign(ElementType!R val, size_t n);

@property Cycle save();

enum auto opDollar;

auto opSlice(size_t i, size_t j);

auto opSlice(size_t i, DollarToken);
範囲のプリミティブ
struct Zip(Ranges...) if (Ranges.length && allSatisfy!(isInputRange, Ranges));

auto zip(Ranges...)(Ranges ranges)
if (Ranges.length && allSatisfy!(isInputRange, Ranges));

auto zip(Ranges...)(StoppingPolicy sp, Ranges ranges)
if (Ranges.length && allSatisfy!(isInputRange, Ranges));
複数の範囲をロックステップで反復する。要素型はプロキシタプルであり、n番目の範囲の現在の要素にアクセスするには、e[n] を使用する。
zipはxml-ph-0000@deepl.internalに似ているが、 lockstepが、lockstep は 要素を束ねず、opApply プロトコルを使用する。 lockstep は、foreach 回の反復で要素への参照アクセスを許可する。
Parameters:
StoppingPolicy sp zip範囲の長さが異なる場合の動作を制御する
Ranges ranges zipで結合する
Returns:
少なくとも、入力範囲。 Zipすべてのコンポーネントの中で最も低いレンジ機能を提供する。 例えば、すべてのレンジがランダムアクセスを提供している場合にのみ、ランダムアクセスを提供する。また、すべてのレンジが提供している場合にのみ、変更や交換も提供する。 このため、 Zip複数の範囲を同時に操作できるため、非常に強力である。
Throws:
すべての範囲の長さが同じでない場合、ExceptionspStoppingPolicy.requireSameLength に設定されている。
制限事項 xml-ph-0000@deepl.internal および xml-ph-0001@deepl.internal 属性は推測できない。

制限事項@nogc およびnothrow 属性は、 struct に対して推論できない。 Zip実行時に異なる可能性があるため、 StoppingPolicy実行時に変化する可能性があるためです。この 制限は、xml-ph-0000@deepl.internal を引数として明示的に指定されていない場合に、 zip StoppingPolicy を引数として指定しない場合、関数によって返される匿名の範囲にはこの制限は適用されない。

xml-ph-0000@deepl.internalxml-ph-0000@deepl.internal
Examples:
import std.algorithm.comparison : equal;
import std.algorithm.iteration : map;

// pairwise sum
auto arr = only(0, 1, 2);
auto part1 = zip(arr, arr.dropOne).map!"a[0] + a[1]";
assert(part1.equal(only(1, 3)));
xml-ph-0000@deepl.internalxml-ph-0000@deepl.internal
Examples:
import std.conv : to;

int[] a = [ 1, 2, 3 ];
string[] b = [ "a", "b", "c" ];
string[] result;

foreach (tup; zip(a, b))
{
    result ~= tup[0].to!string ~ tup[1];
}

writeln(result); // ["1a", "2b", "3c"]

size_t idx = 0;
// foreachでタプル要素を展開する
foreach (e1, e2; zip(a, b))
{
    writeln(e1); // a[idx]
    writeln(e2); // b[idx]
    ++idx;
}
Examples: 強力である。次のコードは、2つの配列を並行してソートする。
zip強力である。次のコードは、2つの配列を並列でソートする。
import std.algorithm.sorting : sort;

int[] a = [ 1, 2, 3 ];
string[] b = [ "a", "c", "b" ];
zip(a, b).sort!((t1, t2) => t1[0] > t2[0]);

writeln(a); // [3, 2, 1]
// bはaのソートに従ってソートされる
writeln(b); // ["b", "c", "a"]
parallel並列
オブジェクトを構築する。通常、これは間接的に使用することで呼び出される
this(R rs, StoppingPolicy s = StoppingPolicy.shortest);
オブジェクトを構築する。通常、これは関数を使用して間接的に呼び出される zip関数を使用して間接的に呼び出される。
enum bool empty;
範囲が末尾の場合、true を返す。テストは 停止ポリシーに依存する。
@property Zip save();
@property ElementType front();
現在の反復処理対象の要素を返す。
@property void front(ElementType v);
反復処理されるすべての範囲の先頭を設定する。
ElementType moveFront();
先頭の要素を削除する。
@property ElementType back();
右端の要素を返す。
ElementType moveBack();
後ろを移動する。
右端の要素を返す。
@property void back(ElementType v);
現在の反復処理中の要素を返す。
右端の要素を返す。
void popFront();
すべての制御された範囲で次の要素に進む。
void popBack();
popBackすべての制御された範囲を呼び出す。
@property auto length();
この範囲の長さを返す。すべての範囲が定義されている場合にのみ定義される length
alias opDollar = length;
この範囲の長さを返す。すべての範囲が定義されている場合にのみ定義される length
auto opSlice(size_t from, size_t to);
範囲のスライスを返す。すべての範囲でスライスが定義されている場合のみ定義される。
ElementType opIndex(size_t n);
n複合範囲の第th要素を返す。すべての 範囲がランダムアクセス可能である場合に定義される。
void opIndexAssign(ElementType v, size_t n);
複合範囲の n複合範囲の第 番目の要素に割り当てる。すべての範囲がランダムアクセス可能である場合に定義される。
合成範囲の n複合範囲の第 番目の要素を返す。すべての範囲がランダムアクセス可能である場合に定義される。
ElementType moveAt(size_t n);
複合範囲の n複合範囲の 番目の要素を読み取る。すべての範囲がランダムアクセス可能である場合に定義される。
n複合範囲の 番目の要素を返す。すべての範囲がランダムアクセス可能である場合に定義される。
反復処理方法を指定する。
enum StoppingPolicy: int;
反復処理方法を指示する ziplockstep。 デフォルトでは、すべての範囲のうち最も短い範囲の終わりで停止する。
range範囲
Examples:
import std.algorithm.comparison : equal;
import std.exception : assertThrown;
import std.range.primitives;
import std.typecons : tuple;

auto a = [1, 2, 3];
auto b = [4, 5, 6, 7];

auto shortest = zip(StoppingPolicy.shortest, a, b);
assert(shortest.equal([
    tuple(1, 4),
    tuple(2, 5),
    tuple(3, 6)
]));

auto longest = zip(StoppingPolicy.longest, a, b);
assert(longest.equal([
    tuple(1, 4),
    tuple(2, 5),
    tuple(3, 6),
    tuple(0, 7)
]));

auto same = zip(StoppingPolicy.requireSameLength, a, b);
same.popFrontN(3);
assertThrown!Exception(same.popFront);
shortest
最も短い範囲がすべて処理された時点で停止する
longest
最長の範囲が尽きた時点で停止する
requireSameLength
すべての範囲が等しいことを要求する
xml-ph-0000@deepl.internalループを使用して、複数の範囲をロックステップで反復する。
struct Lockstep(Ranges...) if (Ranges.length > 1 && allSatisfy!(isInputRange, Ranges));

Lockstep!Ranges lockstep(Ranges...)(Ranges ranges)
if (allSatisfy!(isInputRange, Ranges));

Lockstep!Ranges lockstep(Ranges...)(Ranges ranges, StoppingPolicy s)
if (allSatisfy!(isInputRange, Ranges));
foreach ループを使用して、複数の範囲をロックステップで反復する。 zip、その要素への参照アクセスが可能である。単一の 範囲のみが渡された場合、 Lockstepエイリアスが作成される。 範囲の長さが異なると、 sStoppingPolicy.shortest 短い方の範囲が空になった時点で終了する。範囲の長さが異なり sStoppingPolicy.requireSameLength の場合は、例外をスローする 。 sStoppingPolicy.longest ではない可能性があり、これを渡すと 例外がスローされる。
反復処理を Lockstep逆順でインデックス付きで反復処理できるのは、 sStoppingPolicy.requireSameLength の場合のみ、インデックスを維持するために 可能である。逆順で反復しようとした場合、 sStoppingPolicy.shortest例外がスローされます。
デフォルトでは、StoppingPolicyStoppingPolicy.shortest に設定されています。

制限事項 pure@safe@nogc 、またはnothrow の属性は、 反復を推測できない。 lockstepzip最初の2つは、実装が異なるため推測できる。

See Also: xml-ph-0000@deepl.internal
zip
lockstepは似ているが、xml-ph-0000@deepl.internalは 要素をバンドルし、範囲を返す。 zipが、zip は要素をバンドルし、 範囲を返す。 lockstep参照アクセスもサポートしている。zip の結果を範囲関数に渡したい場合は、 を使用する。
Examples:
auto arr1 = [1,2,3,4,5,100];
auto arr2 = [6,7,8,9,10];

foreach (ref a, b; lockstep(arr1, arr2))
{
    a += b;
}

writeln(arr1); // [7, 9, 11, 13, 15, 100]

/// Lockstepは、インデックス変数を使用した反復処理もサポートしている:
foreach (index, a, b; lockstep(arr1, arr2))
{
    writeln(arr1[index]); // a
    writeln(arr2[index]); // b
}
this(R ranges, StoppingPolicy sp = StoppingPolicy.shortest);
struct Recurrence(alias fun, StateType, size_t stateSize);

Recurrence!(fun, CommonType!State, State.length) recurrence(alias fun, State...)(State initial);
初期値と、既存の値から次の値を計算する再帰関数を与えられた数学的シーケンスを作成する。 シーケンスは無限の順方向の範囲の形式で得られる。 "型"自体は直接使用されることはほとんどなく、 ほとんどの場合、再帰は関数xml-ph-0000@deepl.internalを呼び出すことで得られる。 Recurrenceそれ自体は直接使用されることはほとんどなく、 通常は関数recurrence を呼び出すことで再帰が取得される。
呼び出す際には、 recurrence、次の値を計算する関数が テンプレート引数として指定され、再帰の初期値が通常の引数として渡される。例えば、 フィボナッチ数列では、初期値は2つ(したがって 状態サイズは2)である。なぜなら、次のフィボナッチ値を計算するには 過去2つの値が必要だからである。
この関数のシグネチャは次のようになる。
auto fun(R)(R state, size_t n)
ここで、n は現在の値のインデックス、state は 配列インデックス記法でインデックス化できる不明瞭な状態ベクトルstate[i] となる。i の有効な値の範囲は、(n - 1) から(n - State.length) である。
関数が文字列形式で渡された場合、状態の名前は"a"、 再帰のゼロベースのインデックスの名前は"n" となる。 与えられた文字列は、a[n] に対して、a[n - 1]a[n - 2]a[n - 3] 、...、a[n - stateSize] を与えた場合に、目的の値を返さなければならない。 状態のサイズは、呼び出しに渡された引数の数によって決まる。 recurrenceRecurrence構造体自体が 再帰の状態を管理し、適切にシフトさせる。
state状態
Examples:
import std.algorithm.comparison : equal;

// 文字列形式の関数を使用したフィボナッチ数:
// a[0] = 1、a[1] = 1、a[n+1] = a[n-1] + a[n]を計算する
auto fib = recurrence!("a[n-1] + a[n-2]")(1, 1);
assert(fib.take(10).equal([1, 1, 2, 3, 5, 8, 13, 21, 34, 55]));

// ラムダ形式の関数を使用した階乗:
auto fac = recurrence!((a,n) => a[n-1] * n)(1);
assert(take(fac, 10).equal([
    1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880
]));

// 明示的な形式で関数を使用する三角数:
static size_t genTriangular(R)(R state, size_t n)
{
    return state[n-1] + n;
}
auto tri = recurrence!genTriangular(0);
assert(take(tri, 10).equal([0, 1, 3, 6, 10, 15, 21, 28, 36, 45]));
struct Sequence(alias fun, State);

auto sequence(alias fun, State...)(State args);
SequenceRecurrence と似ているが、反復処理が いわゆる閉形式で提示されている点が異なる。つまり、n番目の要素は 初期値とn 自体から直接計算できる。これは 、 が提供するインターフェースが Sequenceランダムアクセス可能な範囲であることを意味する 。通常のRecurrence は順方向の反復のみを提供するのに対し、
シーケンスの状態はTuple として保存されるため、 異種混合が可能となる。
Examples: 文字列形式の関数を使用して奇数番号:
文字列形式の関数を使用して奇数:
auto odds = sequence!("a[0] + n * a[1]")(1, 2);
writeln(odds.front); // 1
odds.popFront();
writeln(odds.front); // 3
odds.popFront();
writeln(odds.front); // 5
Examples:
三角数、ラムダ形式の関数を使用:
auto tri = sequence!((a,n) => n*(n+1)/2)();

// ランダムアクセスに注意
writeln(tri[0]); // 0
writeln(tri[3]); // 6
writeln(tri[1]); // 1
writeln(tri[4]); // 10
writeln(tri[2]); // 3
Examples: フィボナッチ数、関数を使用した明示的な形式:
フィボナッチ数、明示的な形式の関数を使用:
import std.math.exponential : pow;
import std.math.rounding : round;
import std.math.algebraic : sqrt;
static ulong computeFib(S)(S state, size_t n)
{
    // ビネの公式
    return cast(ulong)(round((pow(state[0], n+1) - pow(state[1], n+1)) /
                             state[2]));
}
auto fib = sequence!computeFib(
    (1.0 + sqrt(5.0)) / 2.0,    // 黄金比
    (1.0 - sqrt(5.0)) / 2.0,    // 黄金比の共役
    sqrt(5.0));

// 演算子[]によるランダムアクセスに注意
writeln(fib[1]); // 1
writeln(fib[4]); // 5
writeln(fib[3]); // 3
writeln(fib[2]); // 2
writeln(fib[9]); // 55
lambda formラムダ形式
auto iota(B, E, S)(B begin, E end, S step)
if ((isIntegral!(CommonType!(B, E)) || isPointer!(CommonType!(B, E))) && isIntegral!S);

auto iota(B, E)(B begin, E end)
if (isFloatingPoint!(CommonType!(B, E)));

auto iota(B, E)(B begin, E end)
if (isIntegral!(CommonType!(B, E)) || isPointer!(CommonType!(B, E)));

auto iota(E)(E end)
if (is(typeof(iota(E(0), end))));

auto iota(B, E, S)(B begin, E end, S step)
if (isFloatingPoint!(CommonType!(B, E, S)));

auto iota(B, E)(B begin, E end)
if (!isIntegral!(CommonType!(B, E)) && !isFloatingPoint!(CommonType!(B, E)) && !isPointer!(CommonType!(B, E)) && is(typeof((ref B b) { ++b; } )) && (is(typeof(B.init < E.init)) || is(typeof(B.init == E.init))));
指定された開始値と終了値にまたがる値の範囲を作成する 。
Parameters: 開始値。
B begin 開始値。
E end 停止基準となる値。この値は 範囲には含まれない。
S step 現在の値に、反復ごとに追加する値。
Returns: 数値の範囲
数値 beginbegin + stepbegin + 2 * step... 、最大値まで、ただし end
2つの引数を持つオーバーロードはstep = 1 である。begin < end && step < 0begin > end && step > 0 、またはbegin == end の場合、空の範囲が 返される。step == 0 の場合、begin == end はエラーとなる。
組み込み型の場合、返される範囲はランダムアクセス範囲である。 ++ をサポートするユーザー定義型の場合、範囲は入力 範囲である。
整数型イオタは、右側からin 演算子もサポートしている。 これは、ステップを考慮し、 範囲の連続する2つの値の間に含まれる場合、その値は含まれないとみなされる。 contains は、inと同じことを行うが、左側から行う。

void main()
{
    import std.stdio;

    // 以下のグループはすべて、同じ出力を生成する:
    // 0 1 2 3 4

    foreach (i; 0 .. 5)
        writef("%s ", i);
    writeln();

    import std.range : iota;
    foreach (i; iota(0, 5))
        writef("%s ", i);
    writeln();

    writefln("%(%s %|%)", iota(0, 5));

    import std.algorithm.iteration : map;
    import std.algorithm.mutation : copy;
    import std.format;
    iota(0, 5).map!(i => format("%s ", i)).copy(stdout.lockingTextWriter());
    writeln();
}
example例

example例
Examples:
import std.algorithm.comparison : equal;
import std.math.operations : isClose;

auto r = iota(0, 10, 1);
assert(equal(r, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]));
assert(equal(r, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]));
assert(3 in r);
assert(r.contains(3)); //同上
assert(!(10 in r));
assert(!(-8 in r));
r = iota(0, 11, 3);
assert(equal(r, [0, 3, 6, 9]));
writeln(r[2]); // 6
assert(!(2 in r));
auto rf = iota(0.0, 0.5, 0.1);
assert(isClose(rf, [0.0, 0.1, 0.2, 0.3, 0.4]));
example例
enum TransverseOptions: int;
の範囲
のオプション (下記
)。
Examples:
import std.algorithm.comparison : equal;
import std.exception : assertThrown;

auto arr = [[1, 2], [3, 4, 5]];

auto r1 = arr.frontTransversal!(TransverseOptions.assumeJagged);
assert(r1.equal([1, 3]));

// constructionにスロー
assertThrown!Exception(arr.frontTransversal!(TransverseOptions.enforceNotJagged));

auto r2 = arr.frontTransversal!(TransverseOptions.assumeNotJagged);
assert(r2.equal([1, 3]));

// 等しい長さを仮定するか確認すると、
// 結果はランダムアクセス可能な範囲になる
writeln(r2[0]); // 1
static assert(!__traits(compiles, r1[0]));
assumeJagged
横断された場合
範囲の要素は 異なる長さを持つと想定される(例えばギザギザ配列
)。
enforceNotJagged
横断は
範囲の要素が
すべて
同じ長さであることを強制する(例えば、すべて同じ長さの配列の配列)。 チェックは、横断範囲が構築された時点で一度だけ実行される 。
assumeNotJagged
横断は、検証を行わずに、範囲の要素がすべて同じ長さであると仮定する 。 このオプションは、 範囲の外部でチェックがすでに実行されている場合に有用である
struct FrontTransversal(Ror, TransverseOptions opt = TransverseOptions.assumeJagged);

FrontTransversal!(RangeOfRanges, opt) frontTransversal(TransverseOptions opt = TransverseOptions.assumeJagged, RangeOfRanges)(RangeOfRanges rr);
範囲の集合が与えられた場合、囲まれた各範囲の最初の要素を横断的に反復する
Examples:
import std.algorithm.comparison : equal;
int[][] x = new int[][2];
x[0] = [1, 2];
x[1] = [3, 4];
auto ror = frontTransversal(x);
assert(equal(ror, [ 1, 3 ][]));
this(RangeOfRanges input);
入力からの構築
enum bool empty;

@property ref auto front();

ElementType moveFront();

void popFront();
順方向範囲プリミティブ
@property FrontTransversal save();
このfrontTransversal を複製する。 注釈: 複製されるのは、 範囲のカプセル化された範囲のみである。 基礎となる範囲は複製されない
@property ref auto back();

void popBack();

ElementType moveBack();
双方向プリミティブ。 isBidirectionalRange!RangeOfRanges の場合に提供される
ref auto opIndex(size_t n);

ElementType moveAt(size_t n);

void opIndexAssign(ElementType val, size_t n);
ラン
ダムアクセスプリミティブ。 isRandomAccessRange!RangeOfRanges && (opt == TransverseOptions.assumeNotJagged || opt == TransverseOptions.enforceNotJagged) が提供されている場合、
提供される
typeof(this) opSlice(size_t lower, size_t upper);
スライシング。RangeOfRanges がスライシングをサポートしており、 インデックス作成をサポートするためのすべての条件が満たされている場合、提供される
struct Transversal(Ror, TransverseOptions opt = TransverseOptions.assumeJagged);

Transversal!(RangeOfRanges, opt) transversal(TransverseOptions opt = TransverseOptions.assumeJagged, RangeOfRanges)(RangeOfRanges rr, size_t n);
範囲の集合が与えられた場合、 n番目の要素を囲む各範囲について、横断的に反復する。この関数は、 他の言語におけるunzip と類似している
Parameters:
opt 関数が想定する範囲の長さを制御する
RangeOfRanges rr
ランダムアクセス可能な範囲の入力範囲
Returns:
最小限、入力範囲。双方向性やランダムアクセスなどの範囲のプリミティブは、 rr の要素型がそれらを提供している場合に与えられる
Examples:
import std.algorithm.comparison : equal;
int[][] x = new int[][2];
x[0] = [1, 2];
x[1] = [3, 4];
auto ror = transversal(x, 1);
assert(equal(ror, [ 2, 4 ]));
Examples:
以下のコードは完全な展開を行う。
import std.algorithm.comparison : equal;
import std.algorithm.iteration : map;
int[][] y = [[1, 2, 3], [4, 5, 6]];
auto z = y.front.walkLength.iota.map!(i => transversal(y, i));
assert(equal!equal(z, [[1, 4], [2, 5], [3, 6]]));
this(RangeOfRanges input, size_t n);
入力とインデックスからの構築。
enum bool empty;

@property ref auto front();

E moveFront();

@property void front(E val);

void popFront();

@property typeof(this) save();
順方向のレンジプリミティブ。
@property ref auto back();

void popBack();

E moveBack();

@property void back(E val);
双方向のプリミティブ。 isBidirectionalRange!RangeOfRanges が提供されている場合、
これらが提供される
ref auto opIndex(size_t n);

E moveAt(size_t n);

void opIndexAssign(E val, size_t n);
ランダムアクセスのプリミティブ。 isRandomAccessRange!RangeOfRanges && (opt == TransverseOptions.assumeNotJagged || opt == TransverseOptions.enforceNotJagged) が提供されている場合、これらが提供される
typeof(this) opSlice(size_t lower, size_t upper);
スライシング。RangeOfRanges がスライシングをサポートしており、 インデックス作成をサポートするためのすべての条件が満たされている場合、これらが提供される
Transposed!(RangeOfRanges, opt) transposed(TransverseOptions opt = TransverseOptions.assumeJagged, RangeOfRanges)(RangeOfRanges rr)
if (isForwardRange!RangeOfRanges && isInputRange!(ElementType!RangeOfRanges) && hasAssignableElements!RangeOfRanges);
範囲の集合が与えられた場合、i番目の部分範囲が 元の部分範囲のi番目の要素を含むような、
範囲の
集合を返す
Parameters:
opt
関数が想定する範囲の長さ(ギザギザがあるかないか)を制御する
RangeOfRanges rr
範囲の集合
Examples:
import std.algorithm.comparison : equal;
int[][] ror = [
    [1, 2, 3],
    [4, 5, 6]
];
auto xp = transposed(ror);
assert(equal!"a.equal(b)"(xp, [
    [1, 4],
    [2, 5],
    [3, 6]
]));
Examples:
int[][] x = new int[][2];
x[0] = [1, 2];
x[1] = [3, 4];
auto tr = transposed(x);
int[][] witness = [ [ 1, 3 ], [ 2, 4 ] ];
uint i;

foreach (e; tr)
{
    writeln(array(e)); // witness[i++]
}
struct Indexed(Source, Indices) if (isRandomAccessRange!Source && isInputRange!Indices && is(typeof(Source.init[ElementType!Indices.init])));

Indexed!(Source, Indices) indexed(Source, Indices)(Source source, Indices indices);
この構造体は、sourceindices の2つの範囲を受け取り、source のビューを作成する。その要素は、indices に従って並べ替えられたかのように。indices は、source の要素のサブセットのみを含み、 要素が繰り返される場合もある
Source はランダムアクセス可能な範囲でなければならない。返される範囲は、Indices が双方向またはランダムアクセスの場合は、それぞれ双方向またはランダムアクセスとなる
Examples:
import std.algorithm.comparison : equal;
auto source = [1, 2, 3, 4, 5];
auto indices = [4, 3, 1, 2, 0, 4];
auto ind = indexed(source, indices);
assert(equal(ind, [5, 4, 2, 3, 1, 5]));
assert(equal(retro(ind), [5, 1, 3, 2, 4, 5]));
@property ref auto front();

void popFront();

@property typeof(this) save();

@property ref auto front(ElementType!Source newVal);

auto moveFront();

@property ref auto back();

void popBack();

@property ref auto back(ElementType!Source newVal);

auto moveBack();

ref auto opIndex(size_t index);

typeof(this) opSlice(size_t a, size_t b);

auto opIndexAssign(ElementType!Source newVal, size_t index);

auto moveAt(size_t index);
範囲のプリミティブ
@property Source source();
ソース範囲を返す。
@property Indices indices();
インデックス範囲を返す
size_t physicalIndex(size_t logicalIndex);
指定された論理インデックスに対応するソース範囲の物理インデックスを返す。 これは、例えば、Indexed にインデックスを付ける際に、別の間接レイヤーを追加せずに使用できる。
Examples:
auto ind = indexed([1, 2, 3, 4, 5], [1, 3, 4]);
writeln(ind.physicalIndex(0)); // 1
struct Chunks(Source) if (isInputRange!Source);

Chunks!Source chunks(Source)(Source source, size_t chunkSize)
if (isInputRange!Source);
この範囲は、固定サイズのチャンクを繰り返し処理する。 chunkSizesourceSource入力範囲でなければならない。chunkSizeゼロより大きい値でなければならない。
!isInfinite!Sourcesource.walkLength均等に割り切れない 場合、 chunkSize場合、この範囲の後ろの要素には 要素が不足することになります chunkSize
Source が前方範囲の場合、結果として得られる範囲も前方範囲となる。 それ以外の場合、結果として得られるチャンクは、同じ入力範囲を消費する入力範囲となる。front を繰り返し実行すると、チャンクが縮小され、front のその後の呼び出しではチャンク全体が返されなくなる。また、popFront を外側の範囲で呼び出すと、front の以前の値への残存する参照がすべて無効になる。
Parameters:
Source source チャンクが選択される範囲
size_t chunkSize チャンクサイズ
See Also:
Returns: チャンクの範囲。
チャンクの範囲。
range範囲
Examples:
import std.algorithm.comparison : equal;
auto source = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
auto chunks = chunks(source, 4);
writeln(chunks[0]); // [1, 2, 3, 4]
writeln(chunks[1]); // [5, 6, 7, 8]
writeln(chunks[2]); // [9, 10]
writeln(chunks.back); // chunks[2]
writeln(chunks.front); // chunks[0]
writeln(chunks.length); // 3
assert(equal(retro(array(chunks)), array(retro(chunks))));
range of chunksチャンクの範囲
Examples: 非順方向の入力範囲はサポートされているが、限定的なセマンティクスとなる。
非順方向の入力範囲はサポートされているが、限定的なセマンティクスとなる。
import std.algorithm.comparison : equal;

int i;

// ジェネレータは状態を保存しないので、順方向の範囲にはできない。
auto inputRange = generate!(() => ++i).take(10);

// まだチャンク単位で処理することはできるが、シングルパスのみとなる。
auto chunked = inputRange.chunks(2);

assert(chunked.front.equal([1, 2]));
assert(chunked.front.empty); // チャンクを繰り返すと、それが消費される
chunked.popFront;
assert(chunked.front.equal([3, 4]));
range範囲
non-forward input range非順方向入力範囲
this(Source source, size_t chunkSize);
標準コンストラクタ
@property auto front();

void popFront();

@property bool empty();
入力範囲のプリミティブ。常に存在する。
@property typeof(this) save();
前方範囲のプリミティブ。Source が前方範囲の場合のみ存在する。
@property size_t length();
長さ。hasLength!Source が長さの場合のみtrue
auto opIndex(size_t index);

typeof(this) opSlice(size_t lower, size_t upper);
インデックスおよびスライス操作。hasSlicing!Sourcetrue の場合のみ提供される。
@property auto back();

void popBack();
双方向の範囲のプリミティブ。 hasSlicing!SourcehasLength!Sourcetrue の場合のみ提供される。
struct EvenChunks(Source) if (isForwardRange!Source && hasLength!Source);

EvenChunks!Source evenChunks(Source)(Source source, size_t chunkCount)
if (isForwardRange!Source && hasLength!Source);
この範囲は、 source範囲を chunkCountほぼ同じ長さの まとまりに分割します。Source は、 長さが既知の
chunksevenChunksチャンクの数(サイズではない)を受け取る。 返される範囲には、source.length / chunkCount + 1 要素が0個以上含まれ、その後ろにsource.length / chunkCount 要素が続く。source.length < chunkCount の場合、一部のチャンクは空になる。
chunkCountゼロにしてはならない。ただし、 sourceそれも空の場合を除いては。
emailemail
Examples:
import std.algorithm.comparison : equal;
auto source = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
auto chunks = evenChunks(source, 3);
writeln(chunks[0]); // [1, 2, 3, 4]
writeln(chunks[1]); // [5, 6, 7]
writeln(chunks[2]); // [8, 9, 10]
this(Source source, size_t chunkCount);
標準コンストラクタ
@property auto front();

void popFront();

@property bool empty();

@property typeof(this) save();
前方範囲のプリミティブ。常に存在する。
const @property size_t length();
長さ
auto opIndex(size_t index);

typeof(this) opSlice(size_t lower, size_t upper);

@property auto back();

void popBack();
インデックス、スライス、双方向操作、および範囲のプリミティブ。hasSlicing!Sourcetrue の場合のみ提供される。
auto slide(Flag!"withPartial" f = Yes.withPartial, Source)(Source source, size_t windowSize, size_t stepSize = 1)
if (isForwardRange!Source);
固定サイズのスライディングウィンドウの反復 サイズ windowSizesource範囲で、カスタムの stepSize
Source の範囲は少なくともForwardRangeでなければならず、 windowSizeゼロより大きい値でなければなりません。
For windowSize = 1範囲を単一要素グループに分割する(別名unflatten )。 windowSize = 2それは似ている。 zip(source, source.save.dropOne)
itit
Parameters:
f 最後の要素が本来あるべきよりも少ない要素数であるかどうかは、 windowSize 無視される(No.withPartial )か、追加される(Yes.withPartial )か
Source source スライドが選択される範囲
size_t windowSize スライディングウィンドウのサイズ
size_t stepSize ウィンドウ間のステップ(デフォルトでは1)
Returns:
双方向性、順方向、ランダムアクセス、スライスを伝搬させたすべてのスライディングウィンドウの範囲。

注釈 パフォーマンスのオーバーヘッドを避けるため、双方向性は 以下の条件を満たす場合のみ利用可能である std.range.primitives.hasSlicing かつ std.range.primitives.hasLengthが真の場合のみです。

See Also:
Examples: ウィンドウを使用して範囲を繰り返す
ウィンドウ付きの範囲を繰り返し処理する
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]]
));
range範囲
Examples: ステップサイズをカスタム設定する(デフォルトは1)
カスタムステップサイズを設定する(デフォルトは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]]
));
stepsizestepsize
Examples: 最後のスライドには、windowSizeよりも少ない要素を使用する
最後のスライドには、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]]
));
windowSizewindowSize
Examples: 長さ2のすべての可能な部分文字列を数える
長さ2のすべての可能な部分文字列を数える
import std.algorithm.iteration : each;

int[dstring] d;
"AGAGA"d.slide!(Yes.withPartial)(2).each!(a => d[a]++);
writeln(d); // ["AG"d:2, "GA"d:2]
substringsubstring
Examples: withPartialは、範囲の最後の要素が完全なサイズを持たない場合にのみ効果がある
withPartialは、範囲の最後の要素が完全なサイズでない場合にのみ効果がある
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]]));
length長さ
auto only(Values...)(return scope Values values)
if (!is(CommonType!Values == void));

auto only()();
valuesすべての要素をその場で保持する範囲にまとめる。
単一の値または複数の離散した値を 範囲を想定しているアルゴリズムに渡す必要がある場合、動的メモリ割り当てを実行することなく 使用できる。
範囲をコピーするとすべての要素がコピーされるため、 関数から安全に返すことができる。同じ理由で、 返された範囲をコピーすると、引数の数が多い場合にはコストが高くなる可能性がある。 "function"関数
rangerange
Parameters:
Values values 一緒に組み立てるべき値
Returns: 組み立てられた値のxml-ph-0000@deepl.internal。xml-ph-0001@deepl.internal 返された範囲はスライスすることができる。その要素は代入することができる。
組み立てられた値のRandomAccessRange
返された範囲はスライスすることができる。その要素は、Values 内のすべての型が範囲の要素型からの代入をサポートしている場合、
See Also:
chain範囲を連結する
rangerange
Examples:
import std.algorithm.comparison : equal;
import std.algorithm.iteration : filter, joiner, map;
import std.algorithm.searching : findSplitBefore;
import std.uni : isUpper;

assert(equal(only('♡'), "♡"));
writeln([1, 2, 3, 4].findSplitBefore(only(3))[0]); // [1, 2]

assert(only("one", "two", "three").joiner(" ").equal("one two three"));

string title = "The D Programming Language";
assert(title
    .filter!isUpper // 大文字を取る
    .map!only       // 各文字をそれぞれの範囲にする
    .joiner(".")    // のんびりと範囲を結合する
    .equal("T.D.P.L"));
auto enumerate(Enumerator = size_t, Range)(Range range, Enumerator start = 0)
if (isIntegral!Enumerator && isInputRange!Range);
添え字変数を付けて繰り返し処理を行う。 range添え字変数を付けて
各要素は、 std.typecons.Tupleインデックスと 要素が順に含まれており、インデックスのメンバーはindex、 要素のメンバーはvalue という名前である。
インデックスは start、反復ごとに1ずつインクリメントされる。

オーバーフロー もし range長さがある場合、"so"に値を渡すことはエラーです。 start ので、 start + range.lengthEnumerator.max より大きくなるため、 オーバーフローが発生しないことが保証される。

もし range長さがなく、popFrontfront.index == Enumerator.max のときに呼び出された場合、インデックスがオーバーフローし、Enumerator.min から継続されます。

Parameters:
Range range インデックスを添付する入力範囲
Enumerator start インデックスのカウンターを何から開始するかを指定する
Returns: 少なくとも、入力範囲。他のすべての範囲の基本要素は、結果として得られる範囲に与えられる。
少なくとも、入力範囲。他のすべての範囲のプリミティブは、 結果として得られる範囲にそれらが存在する場合に与えられる range。例外は双方向の 基本要素で、これは range長さがある場合のみ
例 xml-ph-0000@deepl.internal をインデックスループ変数とともに使用する場合に便利:

インデックスループ変数でforeach を使用する場合に便利:

    import std.stdio : stdin, stdout;
    import std.range : enumerate;

    foreach (lineNum, line; stdin.byLine().enumerate(1))
        stdout.writefln("line #%s: %s", lineNum, line);

Examples:
負のポジションから列挙を開始できる:
import std.array : assocArray;
import std.range : enumerate;

bool[int] aa = true.repeat(3).enumerate(-1).assocArray();
assert(aa[-1]);
assert(aa[0]);
assert(aa[1]);
index負の
xml-ph-0000@deepl.internalが型T1とT2の変数を任意の順序で受け入れる場合、trueを返す。 以下のコードはコンパイルできるはずである。
enum auto isTwoWayCompatible(alias fn, T1, T2);
fn が型T1とT2の変数を任意の順序で受け入れる場合は、trueを返す。 以下のコードはコンパイルできるはずである。
(ref T1 a, ref T2 b)
{
  fn(a, b);
  fn(b, a);
}
any order任意の順序
Examples:
void func1(int a, int b);
void func2(int a, float b);

static assert(isTwoWayCompatible!(func1, int, int));
static assert(isTwoWayCompatible!(func1, short, int));
static assert(!isTwoWayCompatible!(func2, int, float));

void func3(ref int a, ref int b);
static assert( isTwoWayCompatible!(func3, int, int));
static assert(!isTwoWayCompatible!(func3, short, int));
enum SearchPolicy: int;
以下の検索プリミティブlowerBound upperBoundequalRange で使用されるポリシー SortedRange
Examples:
import std.algorithm.comparison : equal;

auto a = assumeSorted([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
auto p1 = a.upperBound!(SearchPolicy.binarySearch)(3);
assert(p1.equal([4, 5, 6, 7, 8, 9]));

auto p2 = a.lowerBound!(SearchPolicy.gallop)(4);
assert(p2.equal([0, 1, 2, 3]));
linear
直線的に検索する。
trot
線形に増加するステップで検索する(1、2、3、...)。 二次探索スケジュール(試行されるインデックスは0、1、 3、6、10、15、21、28、...)につながる。探索が目標値を逸脱すると、 残りの区間は二分探索を用いて探索される。 探索はΟ(sqrt(n))時間で完了する。 "値"が範囲の開始付近にあると 十分に確信できる場合にこれを使用する。
gallop
ギャロッピングサーチアルゴリズムを実行する。すなわち、 ステップが毎回2倍になる検索(1、2、4、8、...)を行い、 指数関数的な検索スケジュール(試行されるインデックスは0、1、3、 7、15、31、63、...)に導く。検索が目標値を上回ると、 残りの間隔は二分探索を使用して検索される。値は Ο(log(n))の時間で発見される。
binarySearch
古典的な間隔半減ポリシーを使用して検索する。 検索は範囲の中央から開始し、各検索ステップで 範囲が半分になる。このポリシーでは、Ο(log(n))の時間で値を見つけることができるが、 大きな範囲ではgallop よりもキャッシュに優しくない 。 binarySearchポリシーは、trotgalloptrotBackwards gallopBackwards の戦略の最後のステップとして使用される。
trotBackwards
trot と同様だが、逆方向から開始する。 値が範囲の終わり付近にあると確信している場合にこれを使用する。
gallopBackwards
gallop と同様だが、逆方向から開始する。 値が範囲の端付近にあると確信している場合に使う。
enum SortedRangeOptions: int;
範囲のオプション(下記) SortedRange範囲(下記)のオプション。
rangerange
Examples:
// 厳密にチェックされたSortedRangeを作成する
SortedRange!(int[],"a < b", SortedRangeOptions.checkStrictly)([ 1, 3, 5, 7, 9 ]);
assumeSorted
範囲は確認せずにソートされていると仮定する。
checkStrictly
範囲のすべての要素がソートされているか確認される。 確認はO(n)の時間で実行される。
checkRoughly
範囲の要素の一部がソートされているか確認される。 ランダムな順序を持つ範囲については、これはほぼ確実に ソートされていないことを検出する。ほぼソートされた範囲については 、失敗する可能性が高い。確認された要素は 決定論的な方法で選択されるため、この確認は再現可能である。 確認はO(log(n))時間で実行される。
struct SortedRange(Range, alias pred = "a < b", SortedRangeOptions opt = SortedRangeOptions.assumeSorted) if (isInputRange!Range && !isInstanceOf!(SortedRange, Range));

template SortedRange(Range, alias pred = "a < b", SortedRangeOptions opt = SortedRangeOptions.assumeSorted) if (isInstanceOf!(SortedRange, Range))
ソート済みの範囲を表す。通常の範囲のプリミティブに加えて、 ソートを活かした追加の操作、例えばマージや二分探索などもサポートする。 ソートされていない範囲r から SortedRange を取得するには、 std.algorithm.sorting.sortr をその場でソートし、対応するものを返す SortedRangeSortedRangeすでにソート済みであることがわかっている範囲 r から、 assumeSorted
Parameters:
Examples:
import std.algorithm.sorting : sort;
auto a = [ 1, 2, 3, 42, 52, 64 ];
auto r = assumeSorted(a);
assert(r.contains(3));
assert(!(32 in r));
auto r1 = sort!"a > b"(a);
assert(3 in r1);
assert(!r1.contains(32));
writeln(r1.release()); // [64, 52, 42, 3, 2, 1]
Examples: ランダムアクセスよりも弱い範囲を受け入れることも可能だが、それらに対して興味深い機能を提供することはできない。したがって、
SortedRangeランダムアクセスよりも弱い範囲を受け入れることも可能だが、 それらに対して興味深い機能を提供することはできない。そのため、SortedRange現在はランダムアクセス可能な範囲に制限されている。
元の範囲のコピーは作成されない。基礎となる範囲が 対応する範囲と併せて変更された場合、 SortedRangeソート順が崩れるような 変更が加えられた場合、 SortedRange動作が不安定になります。
import std.algorithm.mutation : swap;
auto a = [ 1, 2, 3, 42, 52, 64 ];
auto r = assumeSorted(a);
assert(r.contains(42));
swap(a[3], a[5]);         // 本来の範囲パスのソートを解除することは違法だが、
assert(!r.contains(42));  // そうすべきではない
Examples: 、基礎となる範囲の2つの要素を引数として取らない述語で検索できる。xml-ph-0000@deepl.internalこれは、構造体の範囲がソートされている場合に有用である。
SortedRange基礎となる範囲の2つの要素を引数として取らない述語で検索することができます。
これは、構造体の範囲がメンバによってソートされており、 そのメンバの値のみを指定してその範囲内で検索を行いたい場合に便利です。
import std.algorithm.comparison : equal;
static struct S { int i; }
static bool byI(A, B)(A a, B b)
{
    static if (is(A == S))
        return a.i < b;
    else
        return a < b.i;
}
auto r = assumeSorted!byI([S(1), S(2), S(3)]);
auto lessThanTwo = r.lowerBound(2);
assert(equal(lessThanTwo, [S(1)]));
emailemail
@property bool empty();

@property auto save();

@property ref auto front();

void popFront();

@property ref auto back();

void popBack();

ref auto opIndex(size_t i);

scope auto opSlice(size_t a, size_t b) return;
範囲のプリミティブ。
scope auto release() return;
制御された範囲を解放し、それを返す。
これは、その反対の動作を行う。 assumeSorted。範囲をSortedRange に変換するのではなく、SortedRangeから元の範囲を抽出する。 move.std.algorithm.mutation
xml-ph-0001@deepl.internalxml-ph-0001@deepl.internal
Examples:
import std.algorithm.sorting : sort;
int[3] data = [ 1, 2, 3 ];
auto a = assumeSorted(data[]);
writeln(a); // sort!"a < b"(data[])
int[] p = a.release();
writeln(p); // [1, 2, 3]
auto lowerBound(SearchPolicy sp = SearchPolicy.binarySearch, V)(V value)
if (isTwoWayCompatible!(predFun, ElementType!Range, V) && hasSlicing!Range);
この関数は、ポリシーsp を使用して検索を行い、 pred(x, value)true となる左側の最大の部分範囲を、すべてのx について 見つける(例えば、pred が「より小さい」場合は、 要素が厳密に小さい範囲の部分を返す value。検索 スケジュールとその複雑性については、 SearchPolicy
less than未満
Examples:
import std.algorithm.comparison : equal;
auto a = assumeSorted([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]);
auto p = a.lowerBound(4);
assert(equal(p, [ 0, 1, 2, 3 ]));
auto upperBound(SearchPolicy sp = SearchPolicy.binarySearch, V)(V value)
if (isTwoWayCompatible!(predFun, ElementType!Range, V));
この関数は、ポリシーsp に従って、pred(value, x)true となる最大の右部分範囲を、 すべてのxについて検索する(例えば、pred が「未満」の場合は、 要素が厳密に「より大きい」範囲の部分を返す value。検索スケジュールと その複雑性については、 SearchPolicy
ランダムアクセスができない範囲については、SearchPolicy.linearのみが許可されたポリシーである(ユーザーコードが予期せぬ非効率性にさらされないよう、明示的に指定する必要がある )。ランダムアクセス検索については、すべての ポリシーが許可され、SearchPolicy.binarySearch がデフォルトである。
xml-ph-0001@deepl.internalxml-ph-0001@deepl.internal
Examples:
import std.algorithm.comparison : equal;
auto a = assumeSorted([ 1, 2, 3, 3, 3, 4, 4, 5, 6 ]);
auto p = a.upperBound(3);
assert(equal(p, [4, 4, 5, 6]));
auto equalRange(V)(V value)
if (isTwoWayCompatible!(predFun, ElementType!Range, V) && isRandomAccessRange!Range);
e のすべての要素を含む部分範囲を返す。 pred(e, value)pred(value, e) がともにfalse と評価される場合(例えば、 pred が「より小さい」の場合、要素が等しい範囲の部分を返す )。 value。条件を満たす値が見つかるまで、区間を半分に減らす古典的な二分探索を使用し 、その後、左境界を見つけるためにSearchPolicy.gallopBackwards を使用し、 右境界を見つけるためにSearchPolicy.gallop を使用する。 これらのポリシーは、2つの境界が 最初に発見された値の近くにある可能性が高いという事実(すなわち、等しい範囲は比較的小さい)によって正当化される。 全体の探索をΟ(log(n)) 時間で完了する。
Omicronxml-ph-0002@deepl.internal
Examples:
import std.algorithm.comparison : equal;
auto a = [ 1, 2, 3, 3, 3, 4, 4, 5, 6 ];
auto r = a.assumeSorted.equalRange(3);
assert(equal(r, [ 3, 3, 3 ]));
auto trisect(V)(V value)
if (isTwoWayCompatible!(predFun, ElementType!Range, V) && isRandomAccessRange!Range && hasLength!Range);
タプルr を返す。r[0] は、 の結果と同じであり、 は の結果と同じであり、 は lowerBound(value)r[1]equalRange(value) の結果と同じであり、r[2]upperBound(value) の結果と同じである。この呼び出しは、3つを個別に計算するよりも高速である。equalRange と同様の検索スケジュールを使用する。全体の検索を Ο(log(n)) 時間で完了する。
OmicronOmicron
Examples:
import std.algorithm.comparison : equal;
auto a = [ 1, 2, 3, 3, 3, 4, 4, 5, 6 ];
auto r = assumeSorted(a).trisect(3);
assert(equal(r[0], [ 1, 2 ]));
assert(equal(r[1], [ 3, 3, 3 ]));
assert(equal(r[2], [ 4, 4, 5, 6 ]));
bool contains(V)(V value)
if (isRandomAccessRange!Range);
true で見つかった場合のみ、 を返す。 valuerange で見つかった場合のみ、 を返す。 はソート済みであると想定される。predΟ(log(r.length)) 評価を行う。
bool opBinaryRight(string op, V)(V value)
if (op == "in" && isRandomAccessRange!Range);
contains と同様だが、値は範囲の前に指定される。
auto groupBy()();
ソート関係に従って等価な要素のサブレンジのレンジを返す。
auto assumeSorted(alias pred = "a < b", R)(R r)
if (isInputRange!(Unqual!R));
r述語pred によってソートされていると仮定し、 対応するSortedRange!(pred, R)r。 ソート済みかどうかを調べるには、 コスト Ο (n) を使用する。 std.algorithm.sorting.isSorted
xml-ph-0000@deepl.internalxml-ph-0000@deepl.internal
Examples:
import std.algorithm.comparison : equal;

int[] a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
auto p = assumeSorted(a);

assert(equal(p.lowerBound(4), [0, 1, 2, 3]));
assert(equal(p.lowerBound(5), [0, 1, 2, 3, 4]));
assert(equal(p.lowerBound(6), [0, 1, 2, 3, 4, 5]));
assert(equal(p.lowerBound(6.9), [0, 1, 2, 3, 4, 5, 6]));
struct RefRange(R) if (isInputRange!R);

auto refRange(R)(R* range)
if (isInputRange!R);
Wrapperは、参照渡しを効果的に行うことができる。 元のRangeとRefRangeは、常にまったく同じ要素を持つ。 どちらか一方に対して実行された操作は、もう一方にも影響する。例えば、 関数に渡された場合、元のRangeが暗黙的にコピーされる 場合、元のRangeはコピーされず、 参照型であるかのように消費される。

注釈 save は通常通り動作し、新しい範囲に対して操作を行う。そのため、 save が呼び出された場合、 RefRange、保存された範囲での操作は元のファイルには影響しません。

Parameters:
R* range その範囲から RefRange
Returns: A
A RefRange。与えられた範囲がクラス型( したがって、すでに参照型)である場合、元の 範囲が返されるのではなく、 RefRange
Examples: 基本例
基本的な例
import std.algorithm.searching : find;
ubyte[] buffer = [1, 9, 45, 12, 22];
auto found1 = find(buffer, 45);
writeln(found1); // [45, 12, 22]
writeln(buffer); // [1, 9, 45, 12, 22]

auto wrapped1 = refRange(&buffer);
auto found2 = find(wrapped1, 45);
writeln(*found2.ptr); // [45, 12, 22]
writeln(buffer); // [45, 12, 22]

auto found3 = find(wrapped1.save, 22);
writeln(*found3.ptr); // [22]
writeln(buffer); // [45, 12, 22]

string str = "hello world";
auto wrappedStr = refRange(&str);
writeln(str.front); // 'h'
str.popFrontN(5);
writeln(str); // " world"
writeln(wrappedStr.front); // ' '
writeln(*wrappedStr.ptr); // " world"
basic example基本例
Examples: opAssignの例。
opAssignの例。
ubyte[] buffer1 = [1, 2, 3, 4, 5];
ubyte[] buffer2 = [6, 7, 8, 9, 10];
auto wrapped1 = refRange(&buffer1);
auto wrapped2 = refRange(&buffer2);
assert(wrapped1.ptr is &buffer1);
assert(wrapped2.ptr is &buffer2);
assert(wrapped1.ptr !is wrapped2.ptr);
assert(buffer1 != buffer2);

wrapped1 = wrapped2;

//すべてが以前と同じものを指している。
assert(wrapped1.ptr is &buffer1);
assert(wrapped2.ptr is &buffer2);
assert(wrapped1.ptr !is wrapped2.ptr);

//しかし、buffer1は割り当てにより変更された。
writeln(buffer1); // [6, 7, 8, 9, 10]
writeln(buffer2); // [6, 7, 8, 9, 10]

buffer2 = [11, 12, 13, 14, 15];

//すべてが以前と同じものを指している。
assert(wrapped1.ptr is &buffer1);
assert(wrapped2.ptr is &buffer2);
assert(wrapped1.ptr !is wrapped2.ptr);

//しかし、buffer2は割り当てにより変更された。
writeln(buffer1); // [6, 7, 8, 9, 10]
writeln(buffer2); // [11, 12, 13, 14, 15]

wrapped2 = null;

//ポインタはwrap2に対して変更されたが、wrap1に対しては変更されなかった。
assert(wrapped1.ptr is &buffer1);
assert(wrapped2.ptr is null);
assert(wrapped1.ptr !is wrapped2.ptr);

//buffer2は代入の影響を受けない。
writeln(buffer1); // [6, 7, 8, 9, 10]
writeln(buffer2); // [11, 12, 13, 14, 15]
example例
pure nothrow @safe this(R* range);
auto opAssign(RefRange rhs);
これは、xml-ph-0000@deepl.internal のポインタを割り当てない。 rhsこのRefRange に割り当てられるわけではない。 むしろ、 rhsこのRefRange が指す範囲に割り当てられる。 これは、RefRange に対するすべての操作は、 元の範囲に対して行われた場合と同じであるためである。 例外は、RefRangenull に直接または rhsnull である場合です。その場合、RefRangeは もはや元の範囲を指すのではなく、null となります。
void opAssign(typeof(null) rhs);
inout pure nothrow @property @safe inout(R*) ptr();
折り返された範囲へのポインタ。
@property auto front();

const @property auto front();

@property auto front(ElementType!R value);
@property bool empty();

const @property bool empty();
void popFront();
@property auto save();

const @property auto save();

auto opSlice();

const auto opSlice();
isForwardRange!Rtrue の場合にのみ定義される。
@property auto back();

const @property auto back();

@property auto back(ElementType!R value);

void popBack();
isBidirectionalRange!Rtrue の場合にのみ定義される。
ref auto opIndex(IndexType)(IndexType index);

const ref auto opIndex(IndexType)(IndexType index);
isRandomAccessRange!Rtrue の場合にのみ定義される。
auto moveFront();
hasMobileElements!RisForwardRange!Rtrue の場合のみ定義される。
auto moveBack();
hasMobileElements!RisBidirectionalRange!Rtrue の場合のみ定義される。
auto moveAt(size_t index);
hasMobileElements!RisRandomAccessRange!Rtrue の場合のみ定義される。
@property size_t length();

const @property size_t length();

alias opDollar = length;
hasLength!Rtrue の場合にのみ定義される。
auto opSlice(IndexType1, IndexType2)(IndexType1 begin, IndexType2 end);

const auto opSlice(IndexType1, IndexType2)(IndexType1 begin, IndexType2 end);
hasSlicing!Rtrue の場合にのみ定義される。
auto bitwise(R)(auto ref R range)
if (isInputRange!R && isIntegral!(ElementType!R));
整数の型範囲におけるビット単位のアダプター。範囲の要素をビット単位で、 最下位ビットから最上位ビットまで
Parameters:
R 整数の入力範囲を反復処理する
R range ビットずつ消費する
Returns: xml-ph-0000@deepl.internal 入力範囲を順方向に伝搬させ、双方向およびランダムアクセス機能を備えた
Bitwise 入力範囲を順方向に伝搬し、双方向 およびランダムアクセス機能を備えた
Examples:
import std.algorithm.comparison : equal;
import std.format : format;

// 00000011 00001001
ubyte[] arr = [3, 9];
auto r = arr.bitwise;

// 他の範囲と同じようにそれを反復する
writeln(format("%(%d%)", r)); // "1100000010010000"
assert(format("%(%d%)", r.retro).equal("1100000010010000".retro));

auto r2 = r[5 .. $];
// ビットをセットする
r[2] = 1;
writeln(arr[0]); // 7
writeln(r[5]); // r2[0]
Examples: ビット単位で使用することで、均一なブール値ジェネレータを実装できる
ビット単位で使用することで、均一なブール値ジェネレータを実装できる
import std.algorithm.comparison : equal;
import std.random : rndGen;

auto rb = rndGen.bitwise;
static assert(isInfinite!(typeof(rb)));

auto rb2 = rndGen.bitwise;
// 構造体は値で渡されることをお忘れなく
assert(rb.take(10).equal(rb2.take(10)));
boolbool
struct NullSink;

ref auto nullSink();
受け取ったデータを破棄するOutputRange。
range範囲
Examples:
import std.algorithm.iteration : map;
import std.algorithm.mutation : copy;
[4, 5, 6].map!(x => x * 2).copy(nullSink); // データは捨てられる
rangerange
Examples:
import std.csv : csvNextToken;

string line = "a,b,c";

// 最初の列を無視する
line.csvNextToken(nullSink, ',', '"');
line.popFront;

// 2列目を見る
Appender!string app;
line.csvNextToken(app, ',', '"');
writeln(app.data); // "b"
auto tee(Flag!"pipeOnPop" pipeOnPop = Yes.pipeOnPop, R1, R2)(R1 inputRange, R2 outputRange)
if (isInputRange!R1 && isOutputRange!(R2, ElementType!R1));

auto tee(alias fun, Flag!"pipeOnPop" pipeOnPop = Yes.pipeOnPop, R1)(R1 inputRange)
if (is(typeof(fun) == void) || isSomeFunction!fun);
入力範囲を包み込む「ティー」スタイルのパイプを実装し、その範囲の要素を 指定された関数に渡したり、 OutputRange。これは、長い範囲のコードの連鎖の中で中間値を印刷する場合に有用である 。また、front またはpopFront への各呼び出しで副作用のある操作を実行する場合や、 補助的なものに範囲の要素を転用する場合にも OutputRange
結果として得られる範囲は遅延評価されるため、 関数を受け取るバージョンの場合、 tee関数を受け取るバージョンでは、関数は 実際に実行されるのは、範囲を評価する関数を使用してその範囲が「処理」されるまで std.array.arrayまたは std.algorithm.iteration.fold
Parameters: xml-ph-0000@deepl.internal の場合、xml-ph-0001@deepl.internal を呼び出すことなく、単に範囲を反復するだけで十分である。
pipeOnPop Yes.pipeOnPop の場合、front を呼び出すことなく、単に範囲を反復するだけで 十分である。 tee要素をミラーリングする outputRange(または、 それぞれfun )。popFront() の呼び出しは、 新しい値ではなく、古いfront の値をミラーリングすることに注意。つまり、 範囲が空になるまで反復されない場合、最後の値は転送されない。No.pipeOnPop の場合、front が呼び出された要素のみが outputRangefun 。同じ要素に対してfront が2回呼び出された場合でも、 送信されるのは1回のみである。このキャッシュが不要な場合は、 代わりに std.algorithm.iteration.map
R1 inputRange 渡される入力の範囲。
R2 outputRange この範囲には、 inputRange反復処理が進むにつれて 順次受け取ります。
fun この関数は、反復処理が進むにつれて、要素が順次呼び出される inputRange 反復処理が進むにつれて、
Returns:
要素を提供する入力範囲 inputRangeinputRangeより強力な範囲(前方、双方向など)であるかどうかに関わらず、 結果は常に入力範囲となります。これを読み込むと、 inputRange繰り返し実行され、順番に要素が返されます。さらに、同じ要素が outputRangeまたはfun にも渡される。
to xml-ph-0000@deepl.internalxml-ph-0000@deepl.internal
Examples:
import std.algorithm.comparison : equal;
import std.algorithm.iteration : filter, map;

// コピーしながら値を合計する
int[] values = [1, 4, 9, 16, 25];
int sum = 0;
auto newValues = values.tee!(a => sum += a).array;
assert(equal(newValues, values));
writeln(sum); // 1 + 4 + 9 + 16 + 25

// 最初のフィルターを通過した値を数える
int count = 0;
auto newValues4 = values.filter!(a => a < 10)
                        .tee!(a => count++)
                        .map!(a => a + 1)
                        .filter!(a => a < 10);

//Fine。equalは、渡された遅延範囲も評価する。
//equalがnewValues4を評価するまでcountは3にならない
assert(equal(newValues4, [2, 5]));
writeln(count); // 3
auto padLeft(R, E)(R r, E e, size_t n)
if ((isInputRange!R && hasLength!R || isForwardRange!R) && !is(CommonType!(ElementType!R, E) == void));
入力範囲の長さを拡張する r範囲の先頭を要素で埋めることで、 e。要素は e範囲の要素型と共通の型でなければなりません。 r定義されている std.traits.CommonType。 もし nの長さが r場合、 r変更されずに返されます。
もし rUnicode 文字を含む文字列である場合、 padLeft文字列の長さに関するDの規則に従う。 これは文字の数ではなく、 表記素の数でもない。代わりに、エンコーディング単位の数である。各表記素を エンコーディング単位の長さ1つ分として扱いたい場合は、std.uni.byGraphemeこの関数を呼び出す前に
もし r長さがある場合は、これはΟ(1) となります。それ以外の場合、これはΟ(r.length) となります。
Parameters:
R r 長さを持つ入力範囲、または前方一致する範囲
E e 要素で、パディングする
size_t n パディングする長さの
Returns: 元の範囲の要素を含む範囲で、余分なパディングが追加されている xml-ph-0000@deepl.internal 関連項目:
元の範囲の要素を含む範囲で、余分なパディングが追加されている
関連項目: std.string.leftJustifier
element要素
Examples:
import std.algorithm.comparison : equal;

assert([1, 2, 3, 4].padLeft(0, 6).equal([0, 0, 1, 2, 3, 4]));
assert([1, 2, 3, 4].padLeft(0, 3).equal([1, 2, 3, 4]));

assert("abc".padLeft('_', 6).equal("___abc"));
auto padRight(R, E)(R r, E e, size_t n)
if (isInputRange!R && !isInfinite!R && !is(CommonType!(ElementType!R, E) == void));
入力範囲の長さを拡張するには、 r範囲の末尾を 要素で埋めることで e。要素は e範囲の要素型と共通の型でなければなりません。 r定義されている std.traits.CommonType。 もし nの長さが r場合は、その内容が r返されます。
結果として得られる範囲が提供する範囲のプリミティブは、それが提供するかどうかによって異なる r それらを提供するかどうかによって異なります。backpopBack という関数を除いて、 範囲の長さも必要となります。backpopBackも同様です。
Parameters:
R r 長さを持つ入力範囲
E e 要素で範囲をパディングする
size_t n パディングする長さ
Returns: 元の範囲の要素を含む範囲で、余分なパディングが追加されている xml-ph-0000@deepl.internal 関連項目:
元の範囲の要素を含む範囲に、余分なパディングを追加したもの
関連項目: std.string.rightJustifier
element要素
Examples:
import std.algorithm.comparison : equal;

assert([1, 2, 3, 4].padRight(0, 6).equal([1, 2, 3, 4, 0, 0]));
assert([1, 2, 3, 4].padRight(0, 4).equal([1, 2, 3, 4]));

assert("abc".padRight('_', 6).equal("abc___"));
enum auto isSomeFiniteCharInputRange(R);
これは、phobosでよく使用される、あらゆる種類の文字列パラメータを受け入れるためのイディオムを簡素化する。R という型は、例えば単純な文字列、連結文字列などであるstd.range.chainstd.path.chainPathまたはその他の文字の範囲を入力として 使用できます。
この制約では、有限長の文字列のみが許可される。
このテンプレートは次のものと同義である。
isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R)
to beだ
Examples:
import std.path : chainPath;
import std.range : chain;

void someLibraryMethod(R)(R argument)
if (isSomeFiniteCharInputRange!R)
{
    // 実装の詳細については、引数の各文字を繰り返し処理する
}

someLibraryMethod("simple strings work");
someLibraryMethod(chain("chained", " ", "strings", " ", "work"));
someLibraryMethod(chainPath("chained", "paths", "work"));
// 文字の範囲を実装したカスタム構造体を使用することもできる
to beだ