What are all the array initialization syntaxes that are possible with C#?
These are the current declaration and initialization methods for a simple array.
string[] array = new string[2]; // creates array of length 2, default values
string[] array = new string[] { "A", "B" }; // creates populated array of length 2
string[] array = { "A" , "B" }; // creates populated array of length 2
string[] array = new[] { "A", "B" }; // created populated array of length 2
Note that other techniques of obtaining arrays exist, such as the Linq ToArray() extensions on IEnumerable<T>.
Also note that in the declarations above, the first two could replace the string[] on the left with var (C# 3+), as the information on the right is enough to infer the proper type. The third line must be written as displayed, as array initialization syntax alone is not enough to satisfy the compiler's demands. The fourth could also use inference. So if you're into the whole brevity thing, the above could be written as
var array = new string[2]; // creates array of length 2, default values
var array = new string[] { "A", "B" }; // creates populated array of length 2
string[] array = { "A" , "B" }; // creates populated array of length 2
var array = new[] { "A", "B" }; // created populated array of length 2
The array creation syntaxes in C# that are expressions are:
new int[3]
new int[3] { 10, 20, 30 }
new int[] { 10, 20, 30 }
new[] { 10, 20, 30 }
In the first one, the size may be any non-negative integral value and the array elements are initialized to the default values.
In the second one, the size must be a constant and the number of elements given must match. There must be an implicit conversion from the given elements to the given array element type.
In the third one, the elements must be implicitly convertible to the element type, and the size is determined from the number of elements given.
In the fourth one the type of the array element is inferred by computing the best type, if there is one, of all the given elements that have types. All the elements must be implicitly convertible to that type. The size is determined from the number of elements given. This syntax was introduced in C# 3.0.
There is also a syntax which may only be used in a declaration:
int[] x = { 10, 20, 30 };
The elements must be implicitly convertible to the element type. The size is determined from the number of elements given.
there isn't an all-in-one guide
I refer you to C# 4.0 specification, section 7.6.10.4 "Array Creation Expressions".
Non-empty arrays
var data0 = new int[3]
var data1 = new int[3] { 1, 2, 3 }
var data2 = new int[] { 1, 2, 3 }
var data3 = new[] { 1, 2, 3 }
var data4 = { 1, 2, 3 } is not compilable. Use int[] data5 = { 1, 2, 3 } instead.
Empty arrays
var data6 = new int[0]
var data7 = new int[] { }
var data8 = new [] { } and int[] data9 = new [] { } are not compilable.
var data10 = { } is not compilable. Use int[] data11 = { } instead.
As an argument of a method
Only expressions that can be assigned with the var keyword can be passed as arguments.
Foo(new int[2])
Foo(new int[2] { 1, 2 })
Foo(new int[] { 1, 2 })
Foo(new[] { 1, 2 })
Foo({ 1, 2 }) is not compilable
Foo(new int[0])
Foo(new int[] { })
Foo({}) is not compilable
Enumerable.Repeat(String.Empty, count).ToArray()
Will create array of empty strings repeated 'count' times. In case you want to initialize array with same yet special default element value. Careful with reference types, all elements will refer same object.
In case you want to initialize a fixed array of pre-initialized equal (non-null or other than default) elements, use this:
var array = Enumerable.Repeat(string.Empty, 37).ToArray();
Also please take part in this discussion.
var contacts = new[]
{
new
{
Name = " Eugene Zabokritski",
PhoneNumbers = new[] { "206-555-0108", "425-555-0001" }
},
new
{
Name = " Hanying Feng",
PhoneNumbers = new[] { "650-555-0199" }
}
};
Example to create an array of a custom class
Below is the class definition.
public class DummyUser
{
public string email { get; set; }
public string language { get; set; }
}
This is how you can initialize the array:
private DummyUser[] arrDummyUser = new DummyUser[]
{
new DummyUser{
email = "abc.xyz#email.com",
language = "English"
},
new DummyUser{
email = "def#email.com",
language = "Spanish"
}
};
Just a note
The following arrays:
string[] array = new string[2];
string[] array2 = new string[] { "A", "B" };
string[] array3 = { "A" , "B" };
string[] array4 = new[] { "A", "B" };
Will be compiled to:
string[] array = new string[2];
string[] array2 = new string[] { "A", "B" };
string[] array3 = new string[] { "A", "B" };
string[] array4 = new string[] { "A", "B" };
Repeat without LINQ:
float[] floats = System.Array.ConvertAll(new float[16], v => 1.0f);
int[] array = new int[4];
array[0] = 10;
array[1] = 20;
array[2] = 30;
or
string[] week = new string[] {"Sunday","Monday","Tuesday"};
or
string[] array = { "Sunday" , "Monday" };
and in multi dimensional array
Dim i, j As Integer
Dim strArr(1, 2) As String
strArr(0, 0) = "First (0,0)"
strArr(0, 1) = "Second (0,1)"
strArr(1, 0) = "Third (1,0)"
strArr(1, 1) = "Fourth (1,1)"
For Class initialization:
var page1 = new Class1();
var page2 = new Class2();
var pages = new UIViewController[] { page1, page2 };
Another way of creating and initializing an array of objects. This is similar to the example which #Amol has posted above, except this one uses constructors. A dash of polymorphism sprinkled in, I couldn't resist.
IUser[] userArray = new IUser[]
{
new DummyUser("abc#cde.edu", "Gibberish"),
new SmartyUser("pga#lna.it", "Italian", "Engineer")
};
Classes for context:
interface IUser
{
string EMail { get; } // immutable, so get only an no set
string Language { get; }
}
public class DummyUser : IUser
{
public DummyUser(string email, string language)
{
m_email = email;
m_language = language;
}
private string m_email;
public string EMail
{
get { return m_email; }
}
private string m_language;
public string Language
{
get { return m_language; }
}
}
public class SmartyUser : IUser
{
public SmartyUser(string email, string language, string occupation)
{
m_email = email;
m_language = language;
m_occupation = occupation;
}
private string m_email;
public string EMail
{
get { return m_email; }
}
private string m_language;
public string Language
{
get { return m_language; }
}
private string m_occupation;
}
For the class below:
public class Page
{
private string data;
public Page()
{
}
public Page(string data)
{
this.Data = data;
}
public string Data
{
get
{
return this.data;
}
set
{
this.data = value;
}
}
}
you can initialize the array of above object as below.
Pages = new Page[] { new Page("a string") };
Hope this helps.
hi just to add another way:
from this page :
https://learn.microsoft.com/it-it/dotnet/api/system.linq.enumerable.range?view=netcore-3.1
you can use this form If you want to Generates a sequence of integral numbers within a specified range strat 0 to 9:
using System.Linq
.....
public int[] arrayName = Enumerable.Range(0, 9).ToArray();
You can also create dynamic arrays i.e. you can first ask the size of the array from the user before creating it.
Console.Write("Enter size of array");
int n = Convert.ToInt16(Console.ReadLine());
int[] dynamicSizedArray= new int[n]; // Here we have created an array of size n
Console.WriteLine("Input Elements");
for(int i=0;i<n;i++)
{
dynamicSizedArray[i] = Convert.ToInt32(Console.ReadLine());
}
Console.WriteLine("Elements of array are :");
foreach (int i in dynamicSizedArray)
{
Console.WriteLine(i);
}
Console.ReadKey();
Trivial solution with expressions. Note that with NewArrayInit you can create just one-dimensional array.
NewArrayExpression expr = Expression.NewArrayInit(typeof(int), new[] { Expression.Constant(2), Expression.Constant(3) });
int[] array = Expression.Lambda<Func<int[]>>(expr).Compile()(); // compile and call callback
To initialize an empty array, it should be Array.Empty<T>() in dotnet 5.0
For string
var items = Array.Empty<string>();
For number
var items = Array.Empty<int>();
Another way is by calling a static function (for a static object) or any function for instance objects. This can be used for member initialisation.
Now I've not tested all of this so I'll put what I've tested (static member and static function)
Class x {
private static Option[] options = GetOptionList();
private static Option[] GetOptionList() {
return (someSourceOfData).Select(dataitem => new Option()
{field=dataitem.value,field2=dataitem.othervalue});
}
}
What I'd love to know is if there is a way to bypass the function declaration. I know in this example it could be used directly, but assume the function is a little more complex and can't be reduced to a single expression.
I imagine something like the following (but it doesn't work)
Class x {
private static Option[] options = () => {
Lots of prep stuff here that means we can not just use the next line
return (someSourceOfData).Select(dataitem => new Option()
{field=dataitem.value,field2=dataitem.othervalue});
}
}
Basically a way of just declaring the function for the scope of filling the variable.
I'd love it if someone can show me how to do that.
For multi-dimensional array in C# declaration & assign values.
public class Program
{
static void Main()
{
char[][] charArr = new char[][] { new char[] { 'a', 'b' }, new char[] { 'c', 'd' } };
int[][] intArr = new int[][] { new int[] { 1, 2 }, new int[] { 3, 4 } };
}
}
Related
Is there a way for me to say I want some specific values from an array, possibly used in a way such as this?
string[] values = new string[]{"boogie","woogie","all","night"};
string[] refinedValues = values.GetIndexes(new int[]{ 0, 2 });
In this situation, refinedValues would be an array containing the values "boogie" and "all".
You can do this
var refinedValues = new[] { 0, 2 }.Select(values.ElementAt);
A custom extension method would look like this
public static class EnumerableExtensions {
public static IEnumerable<T> GetValues<T>(this IEnumerable<T> enumerable, params Int32[] indices) {
return indices.Select(enumerable.ElementAt);
}
}
Yes, use a bit of LINQ:
string[] values = new string[] { "boogie", "woogie", "all", "night" };
var indexes = new[] {0, 2};
string[] refinedValues = values.Where((e, i) => indexes.Contains(i)).ToArray();
//refined-values contains "boogie", "all"
Let's say I have a list of arrays with contains as below:
var listArray = new List<string[]>():
1st array = {code, ID_1, PK_1, ID_2, PK_2} //Somehow like a header
2nd array = {85734, 32343, 1, 66544, 2}
3rd array = {59382, 23324, 1, 56998, 2}
4rd array = {43234, 45334, 1, 54568, 2}
and these arrays will be added into 'listArray'.
listArray.Add(array);
what should I do for matching the variable inside the list?
e.g: if ID_1 of the array is '32343', ID_2 = '66544'.
// create
var listArray = new List<string[]>():
string whatIWantToFind = "1234";
string[] mySearchArray = new string[] {"1234", "234234", "324234"};
// fill your array here...
// search
foreach(string[] listItem in listArray)
{
// if you want to check a single item inside...
foreach(string item in listItem)
{
// you can compare
if(item == whatIWantToFind)
{
}
// or check if it contains
if(item.Contains(whatIWantToFind))
{
}
}
// to compare everything..
bool checked = true;
for(int i = 0; i < listItem.lenght; i++)
{
if(!listItem[i].Equals(mySearchArray[i])
{
checked = false; break;
}
}
// aha! this is the one
if(checked) {}
}
If you create a class that contains all the data for one array, you can make a master array of those objects. For instance:
public class ListItem {
public string code, ID_1, PK_1, ID_2, PK_2;
}
And then you can use this class:
var listArray = new List<ListItem>();
listArray.add(new ListItem(){ code = 85734, ID_1 = 32343, PK_1 = 1, ID_2 = 66544, PK_2 = 2});
listArray.add(......);
Then, to find the data, you can use a field accessor on the objects in the array:
foreach(var item in listArray)
{
if (item.ID_1.equals("32343") && item.ID_2.equals("66544"))
Console.WriteLine("Found item.");
}
var listArray = new List<string[]>
{
new []{ "code", "ID_1", "PK_1", "ID_2", "PK_2"},
new []{ "85734", "32343", "1", "66544", "2"},
new []{"59382", "23324", "1", "56998", "2"}
};
var index = listArray.First().ToList().IndexOf("ID_1");
var result = listArray.Where((a, i) => i > 0 && a[index] == "32343").ToList();
i want to add new row to table but by passing both normal variables and array variable like the example below
int value1=1;
int value2=2;
int[] numbers = new int[] {3, 4, 5};
DataTable1.Rows.Add(value1,value2,numbers) // numbers as single items so the row will contain 5 values (1,2,3,4,5)
so should i build a new array and pass it ? or there a code spell to do that ?
thanks
This helper method will create a list from 1 to 5:
public IEnumerable<T> GetItemsAndCollectionsAsItems<T>(params object[] itemsAndCollections)
{
var result = new List<T>();
foreach (var itemOrCollection in itemsAndCollections)
{
var collection = itemOrCollection as IEnumerable<T>;
if (collection == null)
{
result.Add((T)itemOrCollection);
}
else
{
result.AddRange(collection);
}
}
return result;
}
And you call it this way:
int value1 = 1;
int value2 = 2;
int[] numbers = new int[] { 3, 4, 5 };
// Returns 1,2,3,4,5
IEnumerable<int> values = GetItemsAndCollectionsAsItems<int>(value1, value2, numbers);
Not sure to be happen with this Int Array but yah, have a look on this link, which stores data same as you want. Simply some tricky things have to do.
I often face the problem to convert the elements of a list to another list with the same elements transformed. Example:
List<string> numbers = ...;
List<int> parsedNumbers = new List<int>();
foreach(var n in numbers)
parsedNumbers.Add(parse(n));
Is it possible in C# to do this mapping in another easier way? Something like numbers.Map(x -> parse(x)).
var parsedNumbers = numbers.Select(n=>int.Parse(n)).ToList();
You can also use List's ConvertAll method.
var parsedNumbers = numbers.ConvertAll(n => int.Parse(n));
AND shorter versions
var parsedNumbers = numbers.Select(int.Parse).ToList();
var parsedNumbers = numbers.ConvertAll(int.Parse);
It looks like you want to use Select from Linq
using System.Linq;
[TestClass]
public class SelectFixture {
private static int Parse(string str) {
return int.Parse(str);
}
[TestMethod]
public void MapStringsToInts() {
var expected = new[] {1, 2, 3, 4, 5};
var strings = new List<string> { "1", "2", "3", "4", "5" };
var numbers = strings.Select(Parse).ToList();
CollectionAssert.AreEquivalent(expected, numbers);
}
}
Let's say I have these two arrays:
var array1 = new[] {"A", "B", "C"};
var array2 = new[] {"A", "C", "D"};
I would like to get the differences between the two. I know I could write this in just a few lines of code, but I want to make sure I'm not missing a built in language feature or a LINQ extension method.
Ideally, I would end up with the following three results:
Items not in array1, but are in array2 ("D")
Items not in array2, but are in array1 ("B")
Items that are in both
If you've got LINQ available to you, you can use Except and Distinct. The sets you asked for in the question are respectively:
- array2.Except(array1)
- array1.Except(array2)
- array1.Intersect(array2)
from the MSDN 101 LINQ samples....
public void Linq52() {
int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 };
int[] numbersB = { 1, 3, 5, 7, 8 };
IEnumerable<int> aOnlyNumbers = numbersA.Except(numbersB);
Console.WriteLine("Numbers in first array but not second array:");
foreach (var n in aOnlyNumbers) {
Console.WriteLine(n);
}
}
Here are the benchmarks of LINQ extension methods. The results were obtained during the development of a real program.
The tests:
2 lists (lst1 and lst2) each approximately 250000 objects. Each object (class Key) contains a string and an integer. The second list mostly contains the same entries as the first one, but some new entries are added and some are removed.
I tested the Except extension method.
var except = lst2.Except(lst1);
List lst = except.ToList();
These 2 lines produced 600 items list of “new additions”. I timed it using the StopWatch object. The speed is astonishing:220 ms. The computer I used is by no means a “speedy Gonzales”. Core 2 Duo T7700 – 2.4GHz.
Note:
Here is the class Key, which implements IEquatable i-face.
public class Key : IEquatable<Key>
{
public int Index { get; private set; }
public string Name { get; private set; }
public Key(string keyName, int sdIndex)
{
this.Name = keyName;
this.Index = sdIndex;
}
// IEquatable implementation
public bool Equals(Key other)
{
//Check whether the compared object is null.
if (Object.ReferenceEquals(other, null)) return false;
//Check whether the compared object references the same data.
if (Object.ReferenceEquals(this, other)) return true;
//Check whether the products' properties are equal.
return Index.Equals(other.Index) && Name.Equals(other.Name);
}
// If Equals() returns true for a pair of objects
// then GetHashCode() must return the same value for these objects.
public override int GetHashCode()
{
//Get hash code for the name field if it is not null.
int hashKeyName = Name == null ? 0 : Name.GetHashCode();
//Get hash code for the index field.
int hashKeyIndex = Index.GetHashCode();
//Calculate the hash code for the Key.
return hashKeyName ^ hashKeyIndex;
}
}
I've had to do things similar to this with very large sets of data. If you're dealing with a few thousand or so, use the Linq stuff since it's much clearer. But if you know that your arrays are pre-sorted, running a merge like this can do it significantly faster, since it only makes one pass through the data and doesn't need to allocate as much memory as the Linq version.
int iA = 0;
int iB = 0;
List<int> inA = new List<int>();
List<int> inB = new List<int>();
List<int> inBoth = new List<int>();
while (iA < numbersA.Length && iB < numbersB.Length)
{
if (numbersA[iA] < numbersB[iB])
{
inA.Add(numbersA[iA++]);
}
else if (numbersA[iA] == numbersB[iB])
{
inBoth.Add(numbersA[iA++]);
++iB;
}
else
{
inB.Add(numbersB[iB++]);
}
}
while (iA < numbersA.Length)
{
inA.Add(numbersA[iA++]);
}
while (iB < numbersB.Length)
{
inB.Add(numbersB[iB++]);
}
Again, this is really only needed if you are dealing with hundreds of thousands of values.
Another solution would be like below as well
int[] arr1 = new int[] { 45, 26, 99, 55, 36 };
int[] arr2 = new int[] { 45, 26, 99, 20, 36 };
var res = arr1.Union(arr2).Except(arr1.Intersect(arr2));