5

配列があるとします。指定された値を持つ配列内のすべての要素を削除したいと思います。誰かがこれを行う方法を知っていますか?削除しようとしている値は複数回発生する可能性があり、配列は必ずしも並べ替えられていません。新しい配列を作成するのではなく、その場で配列をフィルタリングしたいと思います。たとえば2、配列から値を削除[1, 2, 3, 2, 4]すると、結果が生成され[1, 3, 4]ます。

これは私が思いつくことができる最高のものです:

T[] without(T)(T[] stuff, T thingToExclude) {
    auto length = stuff.length;
    T[] result;
    foreach (thing; stuff) {
        if (thing != thingToExclude) {
            result ~= thing;
        }
    }
    return result;
}

stuff = stuff.without(thingToExclude);
writeln(stuff);

これは不必要に複雑で非効率的なようです。もっと簡単な方法はありますか?私は標準ライブラリのstd.algorithmモジュールを見て、何か役立つものを見つけたいと思っていましたが、それが私が望んでいたことを実行するように見えるものはすべて問題がありました。これがうまくいかなかった私が試したもののいくつかの例です:

import std.stdio, std.algorithm, std.conv;

auto stuff = [1, 2, 3, 2, 4];
auto thingToExclude = 2;

/*  Works fine with a hard-coded constant but compiler throws an error when
    given a value unknowable by the compiler:
    variable thingToExclude cannot be read at compile time */
stuff = filter!("a != " ~ to!string(thingToExclude))(stuff);
writeln(stuff);

/*  Works fine if I pass the result directly to writeln but compiler throws
    an error if I try assigning it to a variable such as stuff:
    cannot implicitly convert expression (filter(stuff)) of type FilterResult!(__lambda2,int[]) to int[] */
stuff = filter!((a) { return a != thingToExclude; })(stuff);
writeln(stuff);

/*  Mysterious error from compiler:
    template to(A...) if (!isRawStaticArray!(A)) cannot be sliced with [] */
stuff = to!int[](filter!((a) { return a != thingToExclude; })(stuff));
writeln(stuff);

では、インデックスが表示される場所を知らなくても、配列からすべての値を削除するにはどうすればよいですか?

4

3 に答える 3

10

std.algorithm.filter は、あなたが望むものにかなり近いです.2回目の試行は良いです.

それを新しい変数に割り当てるか、それに対して array() 関数を使用する必要があります。

auto stuffWithoutThing = filter!((a) { return a != thingToExclude; })(stuff);
// use stuffWithoutThing

また

stuff = array(filter!((a) { return a != thingToExclude; })(stuff));

最初のものは新しい配列を作成しません。指定されたものを除外して、繰り返しを提供するだけです。

2 つ目は、新しい配列にコンテンツを保持するためのメモリを割り当てます。std.arrayモジュールを機能させるには、インポートする必要があります。

于 2012-12-27T18:27:20.697 に答える
5

http://dlang.org/phobos/std_algorithm.htmlで関数 remove を調べます。残りの要素の相対位置を維持するかどうかに応じて、安定と不安定の 2 つの戦略があります。どちらの戦略も適切に機能し、O(n) の複雑さがあります。不安定なバージョンでは書き込みが少なくなります。

于 2012-12-28T15:08:46.560 に答える
3

値を削除したい場合は、 remove を使用できます

auto stuffWithoutThing = remove!((a) { return a == thingToExclude; })(stuff);

これは新しい配列を割り当てませんが、その場で機能します。stuff範囲は変更可能である必要があることに注意してください

于 2012-12-27T20:10:19.600 に答える