C#配列に単一の値を入力/インスタンス化する方法は?


205

C#でインスタンス化された値の型の配列には、型のデフォルト値が自動的に入力されることを知っています(たとえば、boolの場合はfalse、intの場合は0など)。

デフォルトではないシード値を配列に自動入力する方法はありますか?作成時またはその後の組み込みメソッド(JavaのArrays.fill()など)のどちらですか?デフォルトではfalseではなくtrueであるブール配列が必要だったとします。これを行う組み込みの方法はありますか、またはforループで配列を反復処理する必要がありますか?

 // Example pseudo-code:
 bool[] abValues = new[1000000];
 Array.Populate(abValues, true);

 // Currently how I'm handling this:
 bool[] abValues = new[1000000];
 for (int i = 0; i < 1000000; i++)
 {
     abValues[i] = true;
 }

配列を反復処理して、各値をtrueに「リセット」する必要があると、効率が悪くなります。とにかくこれはありますか?たぶんすべての値を反転させることによって?

この質問を入力して考えた結果、デフォルト値はC#がバックグラウンドでこれらのオブジェクトのメモリ割り当てを処理する方法の結果であると推測しているので、おそらくこれは不可能だと思います。でも確実に知りたい!


私は通常、名前をis_foundからis_still_hidingに変更します。しかし、答えが大好きです。私は、テストケースのintの配列に対しても同様に行う必要がありました。(良い質問)
ctrl-alt-delor

回答:


146

フレームワークの方法を知らないが、それを行うためのクイックヘルパーを書くことができる。

public static void Populate<T>(this T[] arr, T value ) {
  for ( int i = 0; i < arr.Length;i++ ) {
    arr[i] = value;
  }
}

3
コピーが必要ない場合は、i ++ではなく++ iを使用してください。
void.pointer 2011

24
i ++はiをコピーし、iを増分して、元の値を返します。++ iはインクリメントされた値を返すだけです。したがって、++ iの方が高速です。これは、ここで説明しているような大きなループで重要になる可能性があります。
tenpn

57
@RobertDailey:これはコンパイラの最適化であり、もはや正しくありません。私は自分の信念を検証するためにテストしました。i++の戻り値が何にも使用されない場合、コンパイラーは自動的に++ iとしてコンパイルします。また、戻り値を使用する場合でも、パフォーマンスの差は非常に小さいため、測定するために極端なケースを作成する必要がありました。それでも、実行時間の違いは数パーセントしかありませんでした。
Edward Ned Harvey

8
私はこのような拡張メソッドを書いたが、私はそれのような連鎖する方法を可能にするために、元の配列を返しました:int[] arr = new int[16].Populate(-1);
Gutblender

2
に変更voidするT[]と、次のことが可能になりますvar a = new int[100].Polupate(1)
orad

198
Enumerable.Repeat(true, 1000000).ToArray();

70
これは機能しますが、非常に遅いため、あまり良い解決策ではありません。実際には、forループでの反復より約4倍遅くなります。
patjbs 2009年

4
はい、それは本当です。パフォーマンスを考えるとforループの方が高速です
Rony

6
実際のベンチマークを確認するには、C#Initialize Arrayをご覧ください。
theknut

4
Enumerable.ToArray列挙可能なシーケンスのサイズがわからないため、配列のサイズを推測する必要があります。つまりToArray、のバッファーを超えるたびに配列の割り当てが取得され、最後にトリムの割り当てが1つ追加されます。列挙可能なオブジェクトに関連するオーバーヘッドもあります。
エドワードブレイ

5
参考までに、参照型を使用すると、配列全体が同じ単一オブジェクトへのすべての参照で埋められることに注意してください。これが希望どおりではなく、実際に配列項目ごとに異なるオブジェクトを生成したい場合は、stackoverflow.com/a/44937053/23715を参照してください。
Alex Che

74

千のtrue値を持つ新しい配列を作成します。

var items = Enumerable.Repeat<bool>(true, 1000).ToArray();  // Or ToList(), etc.

同様に、整数シーケンスを生成できます。

var items = Enumerable.Range(0, 1000).ToArray();  // 0..999

8
悪くはないが、それでもforループよりも約4倍遅い
patjbs

1
patjbsは理論的には将来のEnumerable.Repeatは並列実装を使用するため、より高速に実行されます。
Petar Petrov 2010年

1
@PetarPetrovこれは、キャッシュのスラッシングが原因で発生することはありません。CPUキャッシュの性質上、コンピューターが同期作業を期待し、データを適切にロードするため、単一のアレイで並列に作業を実行すると、常に低速になると私はかなり確信しています。
TernaryTopiary 2017年

意図的な悲観化!=早期の最適化の欠如。
Denis Gladkiy

24

大きな配列または可変サイズになる配列の場合は、おそらく以下を使用する必要があります。

Enumerable.Repeat(true, 1000000).ToArray();

小さな配列の場合、C#3でコレクション初期化構文を使用できます。

bool[] vals = new bool[]{ false, false, false, false, false, false, false };

コレクション初期化構文の利点は、各スロットで同じ値を使用する必要がなく、式または関数を使用してスロットを初期化できることです。また、アレイスロットをデフォルト値に初期化するコストを回避できると思います。したがって、たとえば:

bool[] vals = new bool[]{ false, true, false, !(a ||b) && c, SomeBoolMethod() };

float []配列を初期化するには:float[] AlzCalDefault = new float[] {(float) 0.5, 18, 500, 1, 0};
Jim Lahman

配列のFWIWの初期化は以下のようにC#のいずれかのバージョンで行うことができますbool[] vals = { false, true, false, !(a || b) && c, SomeBoolMethod() };
ピーター・バンをHeijden DER

24

配列が非常に大きい場合は、BitArrayを使用してください。(ブールの配列のように)バイトの代わりにすべてのブールに1ビットを使用し、ビット演算子を使用してすべてのビットをtrueに設定することもできます。または、trueで初期化します。あなたがそれを一度だけする必要があるならば、それはより多くの費用がかかるだけです。

System.Collections.BitArray falses = new System.Collections.BitArray(100000, false);
System.Collections.BitArray trues = new System.Collections.BitArray(100000, true);

// Now both contain only true values.
falses.And(trues);

17

Array.Fill.NET Core 2.0以降および.NET Standard 2.1以降で使用できます。


優れた!ただし、これは比較的新しい方法です。.NET Core 2.0+および.NET Standard 2.1で利用できますが、特に.NET Frameworkバージョンでは利用できません。(これは、.NET Frameworkと.NET Coreを組み合わせた.NET 5.0に含まれる予定です)。
アベル

9

残念ながら直接的な方法はないと思いますが、これを行うために配列クラスの拡張メソッドを書くことができると思います

class Program
{
    static void Main(string[] args)
    {
        int[] arr = new int[1000];
        arr.Init(10);
        Array.ForEach(arr, Console.WriteLine);
    }
}

public static class ArrayExtensions
{
    public static void Init<T>(this T[] array, T defaultVaue)
    {
        if (array == null)
            return;
        for (int i = 0; i < array.Length; i++)
        {
            array[i] = defaultVaue;
        }
    }
}

私はこれを掘り下げるほど拡張のアイデアが好きです。場合によっては、事前かつシンプルなソリューションが本当に最高です!
patjbs 2009年

8

さて、もう少しググって読んだ後、私はこれを見つけました:

bool[] bPrimes = new bool[1000000];
bPrimes = Array.ConvertAll<bool, bool>(bPrimes, b=> b=true);

それは確かに私が探しているものに近いです。しかし、それがforループで元の配列を反復処理して値を変更するよりも良いかどうかはわかりません。実際のところ、簡単なテストを行ったところ、約5倍遅くなったように見えます。そのため、実際には良い解決策ではありません。


4
これは、配列内の各要素に対して関数呼び出しを行うことを除いて、実行しようとしていることに似ています。構文的にはもっと見栄えがよくなるかもしれませんが、より多くの作業が行われます...
Nader Shirazie

ええ、それは単にforループが他のことと同様に仕事をするように見えます
patjbs

新しい配列を作成します(元のインスタンスは変更されません)。
Jeppe Stig Nielsen

7

並列実装についてはどうですか

public static void InitializeArray<T>(T[] array, T value)
{
    var cores = Environment.ProcessorCount;

    ArraySegment<T>[] segments = new ArraySegment<T>[cores];

    var step = array.Length / cores;
    for (int i = 0; i < cores; i++)
    {
        segments[i] = new ArraySegment<T>(array, i * step, step);
    }
    var remaining = array.Length % cores;
    if (remaining != 0)
    {
        var lastIndex = segments.Length - 1;
        segments[lastIndex] = new ArraySegment<T>(array, lastIndex * step, array.Length - (lastIndex * step));
    }

    var initializers = new Task[cores];
    for (int i = 0; i < cores; i++)
    {
        var index = i;
        var t = new Task(() =>
        {
            var s = segments[index];
            for (int j = 0; j < s.Count; j++)
            {
                array[j + s.Offset] = value;
            }
        });
        initializers[i] = t;
        t.Start();
    }

    Task.WaitAll(initializers);
}

配列を初期化するだけでは、このコードの威力はわかりませんが、「純粋な」ことは忘れてください。


これは、異なるスレッドがCPUキャッシュラインをめぐって競合するため、シングルスレッドの実装と比較してパフォーマンスが低下するという誤った共有の問題のリスクがあります。これが発生するかどうかは、スレッドごとのメモリブロックのサイズとCPUアーキテクチャによって異なります。
エリックJ.

7

以下のコードは、小さなコピーの単純な反復と大きな​​コピーのArray.Copyを組み合わせたものです

    public static void Populate<T>( T[] array, int startIndex, int count, T value ) {
        if ( array == null ) {
            throw new ArgumentNullException( "array" );
        }
        if ( (uint)startIndex >= array.Length ) {
            throw new ArgumentOutOfRangeException( "startIndex", "" );
        }
        if ( count < 0 || ( (uint)( startIndex + count ) > array.Length ) ) {
            throw new ArgumentOutOfRangeException( "count", "" );
        }
        const int Gap = 16;
        int i = startIndex;

        if ( count <= Gap * 2 ) {
            while ( count > 0 ) {
                array[ i ] = value;
                count--;
                i++;
            }
            return;
        }
        int aval = Gap;
        count -= Gap;

        do {
            array[ i ] = value;
            i++;
            --aval;
        } while ( aval > 0 );

        aval = Gap;
        while ( true ) {
            Array.Copy( array, startIndex, array, i, aval );
            i += aval;
            count -= aval;
            aval *= 2;
            if ( count <= aval ) {
                Array.Copy( array, startIndex, array, i, count );
                break;
            }
        }
    }

int []配列を使用した異なる配列長のベンチマークは次のとおりです。

         2 Iterate:     1981 Populate:     2845
         4 Iterate:     2678 Populate:     3915
         8 Iterate:     4026 Populate:     6592
        16 Iterate:     6825 Populate:    10269
        32 Iterate:    16766 Populate:    18786
        64 Iterate:    27120 Populate:    35187
       128 Iterate:    49769 Populate:    53133
       256 Iterate:   100099 Populate:    71709
       512 Iterate:   184722 Populate:   107933
      1024 Iterate:   363727 Populate:   126389
      2048 Iterate:   710963 Populate:   220152
      4096 Iterate:  1419732 Populate:   291860
      8192 Iterate:  2854372 Populate:   685834
     16384 Iterate:  5703108 Populate:  1444185
     32768 Iterate: 11396999 Populate:  3210109

最初の列は配列サイズで、その後に単純な反復(@JaredPared実装)を使用してコピーする時間が続きます。この方法の時はその後です。これらは、4つの整数の構造体の配列を使用したベンチマークです

         2 Iterate:     2473 Populate:     4589
         4 Iterate:     3966 Populate:     6081
         8 Iterate:     7326 Populate:     9050
        16 Iterate:    14606 Populate:    16114
        32 Iterate:    29170 Populate:    31473
        64 Iterate:    57117 Populate:    52079
       128 Iterate:   112927 Populate:    75503
       256 Iterate:   226767 Populate:   133276
       512 Iterate:   447424 Populate:   165912
      1024 Iterate:   890158 Populate:   367087
      2048 Iterate:  1786918 Populate:   492909
      4096 Iterate:  3570919 Populate:  1623861
      8192 Iterate:  7136554 Populate:  2857678
     16384 Iterate: 14258354 Populate:  6437759
     32768 Iterate: 28351852 Populate: 12843259

7

または...単に反転論理を使用することもできます。ましょfalse平均trueおよびその逆。

コードサンプル

// bool[] isVisible = Enumerable.Repeat(true, 1000000).ToArray();
bool[] isHidden = new bool[1000000]; // Crazy-fast initialization!

// if (isVisible.All(v => v))
if (isHidden.All(v => !v))
{
    // Do stuff!
}

あなたは0失うので、これは、インスタンスint型のために多くの困難となり、すべてけれども面白いソリューション、
MrFox

1
これは、変数名で「論理を逆にする」場合、実際に実行可能なオプションです。bool[] isVisibleそれを作成する代わりにbool[] isHidden
MarkusHütterFeb

1
人々はこれがある種の面白いハックであるように反応するようです。これは一般的な最適化手法です。運が良ければ、コンパイラが代わりにやってくれます。
l33t

4

これも機能します...しかし、不必要かもしれません

 bool[] abValues = new bool[1000];
 abValues = abValues.Select( n => n = true ).ToArray<bool>();

4

ここで提示する答えの多くは、配列を一度に1要素ずつ初期化するループに要約されます。これは、メモリのブロックを一度に操作するように設計されたCPU命令を利用しません。

.Net Standard 2.1(この記事の執筆時点でプレビュー)は、ランタイムライブラリの高性能実装に適したArray.Fill()を提供します(現在のところ、.NET Core その可能性活用して)。 。

以前のプラットフォームの場合、次の拡張メソッドは、配列のサイズが大きい場合、かなりのマージンでささいなループよりも優れています。オンラインコードチャレンジのソリューションが割り当てられた時間予算を約20%超えたときに作成しました。ランタイムが約70%短縮されました。この場合、配列の塗りつぶしは別のループ内で実行されました。BLOCK_SIZEは実験ではなく、直感で設定されました。いくつかの最適化が可能です(たとえば、固定サイズのブロックではなく、目的の値にすでに設定されているすべてのバイトをコピーする)。

internal const int BLOCK_SIZE = 256;
public static void Fill<T>(this T[] array, T value)
{
    if (array.Length < 2 * BLOCK_SIZE)
    {
        for (int i = 0; i < array.Length; i++) array[i] = value;
    }
    else
    {
        int fullBlocks = array.Length / BLOCK_SIZE;
        // Initialize first block
        for (int j = 0; j < BLOCK_SIZE; j++) array[j] = value;
        // Copy successive full blocks
        for (int blk = 1; blk < fullBlocks; blk++)
        {
            Array.Copy(array, 0, array, blk * BLOCK_SIZE, BLOCK_SIZE);
        }

        for (int rem = fullBlocks * BLOCK_SIZE; rem < array.Length; rem++)
        {
            array[rem] = value;
        }
    }
}

3

配列のいくつかの値のみを設定することを計画しているが、ほとんどの場合(カスタム)デフォルト値を取得したい場合は、次のようなことを試すことができます。

public class SparseArray<T>
{
    private Dictionary<int, T> values = new Dictionary<int, T>();

    private T defaultValue;

    public SparseArray(T defaultValue)
    {
        this.defaultValue = defaultValue;
    }

    public T this [int index]
    {
      set { values[index] = value; }
      get { return values.ContainsKey(index) ? values[index] ? defaultValue; }
    }
}

アレイ自体のインターフェイスなど、他のインターフェイスを実装して使用できるようにする必要があります。


3

配列内のすべての要素を単一の操作として設定する方法はありませんが、その値は要素タイプのデフォルト値です。

たとえば、それが整数の配列である場合、次のように1回の操作ですべてをゼロに設定できます。 Array.Clear(...)


2

私はパーティーに遅れていると思いますが、ここにアイデアがあります。ラップされた型の代わりとして使用できるように、ラップされた値との間の変換演算子を持つラッパーを記述します。これは実際には@ l33tからのばかげた答えに触発されました。

最初に(C ++から)C#では、配列の要素が構築されるときにデフォルトのctorが呼び出されないことに気付きました。代わりに、ユーザー定義のデフォルトコンストラクタがある場合でも!-すべての配列要素はゼロで初期化されます。それは私を驚かせました。

したがって、希望する値をデフォルトのctorに提供するラッパークラスは、C ++ではなくC ++の配列に対して機能します。回避策は、変換時にラッパータイプを0から目的のシード値にマッピングさせることです。このように、ゼロの初期化された値は、すべての実用的な目的でシードで初期化されているように見えます。

public struct MyBool
{
    private bool _invertedValue;

    public MyBool(bool b) 
    {   
        _invertedValue = !b;
    }

    public static implicit operator MyBool(bool b)
    {
        return new MyBool(b);
    }

    public static implicit operator bool(MyBool mb)
    {
        return !mb._invertedValue;
    }

}

static void Main(string[] args)
{
        MyBool mb = false; // should expose false.
        Console.Out.WriteLine("false init gives false: " 
                              + !mb);

        MyBool[] fakeBoolArray = new MyBool[100];

        Console.Out.WriteLine("Default array elems are true: " 
                              + fakeBoolArray.All(b => b) );

        fakeBoolArray[21] = false;
        Console.Out.WriteLine("Assigning false worked: " 
                              + !fakeBoolArray[21]);

        fakeBoolArray[21] = true;
        // Should define ToString() on a MyBool,
        // hence the !! to force bool
        Console.Out.WriteLine("Assigning true again worked: " 
                              + !!fakeBoolArray[21]);
}

このパターンは、すべての値タイプに適用できます。たとえば、4での初期化が必要な場合は、intに0から4をマッピングできます。

C ++で可能なようにテンプレートのテンプレートを作成し、シード値をテンプレートパラメータとして提供したいのですが、C#ではそれができないことを理解しています。それとも何か不足していますか?(もちろん、C ++では、配列要素に対して呼び出されるデフォルトのctorを提供できるため、マッピングはまったく必要ありません。)

FWIW、これはC ++での同等物です:https : //ideone.com/wG8yEh


2

ロジックを反転できる場合は、Array.Clear()メソッドを使用してブール配列をfalseに設定できます。

        int upperLimit = 21;
        double optimizeMe = Math.Sqrt(upperLimit);

        bool[] seiveContainer = new bool[upperLimit];
        Array.Clear(seiveContainer, 0, upperLimit);

2

.NET Core、.NET Standard> = 2.1を使用している場合、またはSystem.Memoryパッケージに依存している場合は、次のSpan<T>.Fill()メソッドも使用できます。

var valueToFill = 165;
var data = new int[100];

data.AsSpan().Fill(valueToFill);

// print array content
for (int i = 0; i < data.Length; i++)
{
    Console.WriteLine(data[i]);
}

https://dotnetfiddle.net/UsJ9bu


2

これは、Microsoftが放棄した私たちFrameworkユーザー向けの別のバージョンです。Panos TheofのソリューションEric JPetar Petrovの並列ソリューションの 4倍のArray.Clear速度 4倍の速さで、大規模なアレイでは最大2倍高速です。

まず、関数の祖先を紹介します。これにより、コードが理解しやすくなります。パフォーマンスに関しては、これはPanos Theofのコードとほぼ同等であり、すでに十分な場合もあります。

public static void Fill<T> (T[] array, int count, T value, int threshold = 32)
{
    if (threshold <= 0)
        throw new ArgumentException("threshold");

    int current_size = 0, keep_looping_up_to = Math.Min(count, threshold);

    while (current_size < keep_looping_up_to)
        array[current_size++] = value;

    for (int at_least_half = (count + 1) >> 1; current_size < at_least_half; current_size <<= 1)
        Array.Copy(array, 0, array, current_size, current_size);

    Array.Copy(array, 0, array, current_size, count - current_size);
}

ご覧のとおり、これはすでに初期化された部分を繰り返し2倍にすることに基づいています。これはシンプルで効率的ですが、最新のメモリアーキテクチャでは機能しません。したがって、ダブリングを使用してキャッシュフレンドリーなシードブロックを作成するバージョンが誕生しました。これは、ターゲット領域全体に繰り返しブラストされます。

const int ARRAY_COPY_THRESHOLD = 32;  // 16 ... 64 work equally well for all tested constellations
const int L1_CACHE_SIZE = 1 << 15;

public static void Fill<T> (T[] array, int count, T value, int element_size)
{
    int current_size = 0, keep_looping_up_to = Math.Min(count, ARRAY_COPY_THRESHOLD);

    while (current_size < keep_looping_up_to)
        array[current_size++] = value;

    int block_size = L1_CACHE_SIZE / element_size / 2;
    int keep_doubling_up_to = Math.Min(block_size, count >> 1);

    for ( ; current_size < keep_doubling_up_to; current_size <<= 1)
        Array.Copy(array, 0, array, current_size, current_size);

    for (int enough = count - block_size; current_size < enough; current_size += block_size)
        Array.Copy(array, 0, array, current_size, block_size);

    Array.Copy(array, 0, array, current_size, count - current_size);
}

注:以前のコード(count + 1) >> 1は、2倍のループの制限として必要でした。これにより、最後のコピー操作で、残っているすべてをカバーするのに十分な飼料が確保されます。count >> 1代わりに使用する場合、これは奇数の場合には当てはまりません。現在のバージョンでは、線形コピーループがスラックを拾うため、これは重要ではありません。

-マインドゴーグル-ジェネリックは、将来利用可能になるか、または利用できなくなる可能性がsizeofある制約(unmanaged)を使用しない限り、使用できません。そのため、配列セルのサイズをパラメーターとして渡す必要があります。次の理由により、間違った見積もりは大したことではありませんが、値が正確な場合にパフォーマンスが最高になります。

  • 要素サイズを過小評価すると、ブロックサイズがL1キャッシュの半分よりも大きくなる可能性があるため、コピーソースデータがL1から追い出され、より遅いキャッシュレベルから再フェッチする必要が生じる可能性が高くなります。

  • 要素サイズを過大に見積もると、CPUのL1キャッシュの使用率が低下します。つまり、線形ブロックコピーループは、最適な使用率よりも頻繁に実行されます。したがって、厳密に必要な量よりも多くの固定ループ/呼び出しオーバーヘッドが発生します。

ここに、私のコードを突き刺すベンチマークArray.Clearと、前述した他の3つのソリューションがあります。タイミングはInt32[]、指定されたサイズの整数配列()を満たすためのものです。キャッシュの変化などによる変動を減らすために、各テストは2回続けて実行され、2回目の実行のタイミングが取られました。

array size   Array.Clear      Eric J.   Panos Theof  Petar Petrov   Darth Gizka
-------------------------------------------------------------------------------
     1000:       0,7 µs        0,2 µs        0,2 µs        6,8 µs       0,2 µs 
    10000:       8,0 µs        1,4 µs        1,2 µs        7,8 µs       0,9 µs 
   100000:      72,4 µs       12,4 µs        8,2 µs       33,6 µs       7,5 µs 
  1000000:     652,9 µs      135,8 µs      101,6 µs      197,7 µs      71,6 µs 
 10000000:    7182,6 µs     4174,9 µs     5193,3 µs     3691,5 µs    1658,1 µs 
100000000:   67142,3 µs    44853,3 µs    51372,5 µs    35195,5 µs   16585,1 µs 

このコードのパフォーマンスが十分でない場合、有望な手段は、線形コピーループ(すべてのスレッドが同じソースブロックを使用)を並列化するか、古き良き友人P / Invokeです。

注:ブロックのクリアと入力は通常、MMX / SSE命令などを使用して高度に専門化されたコードに分岐するランタイムルーチンによって行われるため、適切な環境では、それぞれの道徳的同等物を呼び出すだけstd::memsetで、専門的なパフォーマンスレベルが保証されます。IOW、権利により、ライブラリー関数Array.Clearはすべての手巻きバージョンをそのままにしておきます。それが逆になっているという事実は、物事が実際にどれだけ離れているかを示しています。同じFill<>ことは、そもそも自分自身をロールバックする必要がある場合にも当てはまります。なぜなら、それはまだコアとスタンダードだけにあり、フレームワークにはないからです。.NETは今から約20年前から存在しており、最も基本的なものについてはP / Invokeを左右に実行するか、独自にロールバックする必要があります...



0

System.Collections.BitArrayこれは、そのようなコンストラクタを持つ別のアプローチです。

bool[] result = new BitArray(1000000, true).Cast<bool>().ToArray();

または

bool[] result = new bool[1000000];
new BitArray(1000000, true).CopyTo(result, 0);

0

配列を作成する場所にプライベートクラスを作成し、そのためのゲッターとセッターを用意します。配列の各位置をランダムなどの一意にする必要がない限り、intを使用しますか?配列として取得し、位置がnullの場合は取得してその位置を埋め、新しいランダムな値を返します。

IsVisibleHandler
{

  private bool[] b = new bool[10000];

  public bool GetIsVisible(int x)
  {
  return !b[x]
  }

  public void SetIsVisibleTrueAt(int x)
  {
  b[x] = false //!true
  }
}

または使用

public void SetIsVisibleAt(int x, bool isTrue)
{
b[x] = !isTrue;
}

セッターとして。


-2
Boolean[] data = new Boolean[25];

new Action<Boolean[]>((p) => { BitArray seed = new BitArray(p.Length, true); seed.CopyTo(p, 0); }).Invoke(data);

他の人があなたの解決策をよりよく理解できるように、より良い書式設定といくつかの説明の言葉を使用してください。
Gorgsenegger、2014年

1
これを使用して、ターゲットアレイをパーティション化し、シードをさまざまなパーティションにコピーすることで、初期化のパフォーマンスを向上させることができます。これは単にアイデアを与えるためのものでした-これは私の最初の投稿であり、私の最後の投稿でした。
ldsmithperrin 14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.