如何使用单个值填充/实例化 C# 数组?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1014005/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 05:33:26  来源:igfitidea点击:

How to populate/instantiate a C# array with a single value?

c#arraysdefault-value

提问by patjbs

I know that instantiated arrays of value types in C# are automatically populated with the default value of the type(e.g. false for bool, 0 for int, etc.).

我知道 C# 中值类型的实例化数组会自动填充类型默认值(例如,bool 为 false,int 为 0 等)。

Is there a way to auto-populate an array with a seed value that's not the default? Either on creation or a built-in method afterwards (like Java's Arrays.fill())? Say I wanted an boolean array that was true by default, instead of false. Is there a built-in way to do this, or do you just have to iterate through the array with a for loop?

有没有办法用不是默认值的种子值自动填充数组?是在创建时还是之后的内置方法(如 Java 的Arrays.fill())?假设我想要一个默认为 true 而不是 false 的布尔数组。是否有内置的方法可以做到这一点,或者您是否只需要使用 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;
 }

Having to iterate through the array and "reset" each value to true seems ineffecient. Is there anyway around this? Maybe by flipping all values?

必须遍历数组并将每个值“重置”为 true 似乎效率低下。有没有办法解决?也许通过翻转所有值?

After typing this question out and thinking about it, I'm guessing that the default values are simply a result of how C# handles the memory allocation of these objects behind the scenes, so I imagine it's probably not possible to do this. But I'd still like to know for sure!

在输入这个问题并考虑之后,我猜测默认值只是 C# 如何在后台处理这些对象的内存分配的结果,所以我想这可能是不可能的。但我还是想知道!

采纳答案by JaredPar

Don't know of a framework method but you could write a quick helper to do it for you.

不知道框架方法,但您可以编写一个快速助手来为您完成。

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

回答by bytebender

Create a new array with a thousand truevalues:

创建一个包含一千个true值的新数组:

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

Similarly, you can generate integer sequences:

同样,您可以生成整数序列:

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

回答by patjbs

Well after a little more googling and reading I found this:

经过更多的谷歌搜索和阅读,我发现了这一点:

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

Which is certainly closer to what I'm looking for. But I'm not sure if that's better than iterating through the original array in a for-loop and just changing the values. After a quick test in fact, it appears slower by about a factor of 5. So not really a good solution then!

这当然更接近我正在寻找的东西。但我不确定这是否比在 for 循环中迭代原始数组并仅更改值更好。事实上,经过快速测试后,它看起来慢了大约 5 倍。所以这不是一个很好的解决方案!

回答by Rony

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

回答by bashmohandes

unfortunately I don't think there is a direct way, however I think you can write an extension method for the array class to do this

不幸的是,我认为没有直接的方法,但是我认为您可以为数组类编写一个扩展方法来执行此操作

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;
        }
    }
}

回答by Stan R.

this also works...but might be unnecessary

这也有效......但可能是不必要的

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

回答by LBushkin

For large arrays or arrays that will be variable sized you should probably use:

对于大型数组或大小可变的数组,您可能应该使用:

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

For small array you can use the collection initialization syntax in C# 3:

对于小数组,您可以使用 C# 3 中的集合初始化语法:

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

The benefit of the collection initialization syntax, is that you don't have to use the same value in each slot and you can use expressions or functions to initialize a slot. Also, I think you avoid the cost of initializing the array slot to the default value. So, for example:

集合初始化语法的好处是,您不必在每个槽中使用相同的值,您可以使用表达式或函数来初始化槽。另外,我认为您可以避免将数组槽初始化为默认值的成本。因此,例如:

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

回答by MrFox

If your array is so large you should use BitArray. It uses 1 bit for every bool instead of a byte (like in an array of bools) also you can set the all the bits to true with bit operators. Or just initialize on true. If you only need to do it once, it will only cost more though.

如果您的数组太大,您应该使用 BitArray。它为每个 bool 使用 1 位而不是一个字节(如在 bool 数组中),您也可以使用位运算符将所有位设置为 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);

回答by Petar Petrov

What about a parallel implementation

并行实现怎么样

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);
}

When only initializing an array the power of this code can't be seen but I think you should definitely forget about the "pure" for.

当仅初始化数组时,无法看到此代码的强大功能,但我认为您绝对应该忘记“纯”。

回答by Douglas

If you're planning to only set a few of the values in the array, but want to get the (custom) default value most of the time, you could try something like this:

如果您打算只设置数组中的几个值,但想在大多数情况下获得(自定义)默认值,您可以尝试如下操作:

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; }
    }
}

You'll probably need to implement other interfaces to make it useful, such as those on arrayitself.

您可能需要实现其他接口以使其有用,例如数组本身的接口。