I've just started learning C#, I'm good PHP developer and I'm trying to build a basic blackjack app for practice, I'm lost because arrays in PHP and arrays in C# are so different
I'm wondering how I can have the following array which is written in PHP to C#
$array = array("first_array" => array(), "second_array" => array());
I tried the following but it doesn't really seem to work
string[] array = ["first_array" => string[], "second_array" => string[]];
If anyone could help me or guide me, I'd be grateful.
To declare a multi-dimensional string array in C#, it's a simple matter of writing this:
string[,] array = new string[4,4];//size of each array here
Initializing an array is done in the same way as it is in C(++), using curly brackets:
string[,] array = new string[,] { {"index[0][0]", "index[0][1]"}, {"index[1][0]", "index[1][1]"} };
basic tut on arrays in C# here
But you're not creating an array, you're using strings as keys, meaning you need a Dictionary:
Dictionary<string, string[]> dictionary = new Dictionary<string, string[]> {
{"first_array", new string[4]},
{"second_array", new string[4]}
};
In case of a Dictionary, owing to its declaration being quite verbose, it's quite common to see code that relies on C#'s implicit typing to abreviate things a bit:
var dictionary = new Dictionary<string, string[]> {
{"first_array", new string[4]},
{"second_array", new string[4]}
};
more on Dictionary here
Update:
Because you'd like to be able to append strings to the arrays as you go along (ie: you don't know the length of the array when you create it), you can't really use a regular string array. You'll have to use a dictionary of string lists:
var dictionary = new Dictionary<string, List<string>> {
"first_list", new List<string>() { "first string", "second string" },
"second_list", new List<string>() { "first string", "second string" }
};
So now, bringing it all together, and some examples of how you can add strings to lists, and add lists to the dictionary:
//add string to list in dictionary:
dictionary["first_list"].Add("third string");
//suppose we have an array, how to add to the dictionary?
string[] some_array = new string[2] {"string1", "string2"};
//simply initialize list using array of strings
var temp_list = new List<string>(some_array);
//add new key to dictionary
dictionary.Add("new_list", temp_list);
docs on the List<T> class
Note:
Arrays can be resized, so it is possible to use an array instead of a list, but in this case, it's better to use a list. Lists are designed to be resized, arrays are not the best tool for the job
I dont know very much about C#, but that's not the way that works. string[] in C# and in most programming languages indicates an array of strings. You may want to use Dictionary<string key, string[] array> to do that. Don't know if the Dictionary in C# is the same as HashMap in Java, but as I recall, it's the same.
// Two-dimensional array.
int[,] array2D = new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
// The same array with dimensions specified.
int[,] array2Da = new int[4, 2] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
// A similar array with string elements.
string[,] array2Db = new string[3, 2] { { "one", "two" }, { "three", "four" },
{ "five", "six" } };
// Three-dimensional array.
int[, ,] array3D = new int[,,] { { { 1, 2, 3 }, { 4, 5, 6 } },
{ { 7, 8, 9 }, { 10, 11, 12 } } };
// The same array with dimensions specified.
int[, ,] array3Da = new int[2, 2, 3] { { { 1, 2, 3 }, { 4, 5, 6 } },
{ { 7, 8, 9 }, { 10, 11, 12 } } };
for more example http://msdn.microsoft.com/tr-tr/library/2yd9wwz4.aspx
C# is a static typed language, so its arrays can't contain elements of different types.
Your PHP array is a hash actually, so you can use .NET's hash, i.e. Dictionary.
But if your object has only two fixed fields "first_array" and "second_array", then it's better to use the simple class, like this:
public class MyObject
{
public string[] first;
public string[] second;
}
For simple pairs you can use tuples also:
var pair = new Tuple<string[], string[]>({"aa", "bb"}, {"cc", "dd"});
var first = pair.Item1;
var second = pair.Item2;
Related
I can not understand the difference between the declaration with array initialization in the first case and the second
int[] array = new int[3] { 1, 2, 3 };
int[] secondArray = { 1, 2, 3 };
They seem to do the same thing, maybe they work differently?
The is no difference in the result between the two show lines shown:
int[] array = new int[3] { 1, 2, 3 };
int[] secondArray = { 1, 2, 3 };
However, there are practical differences between new int[n] {...} syntax and {...}:
Implicit type is not available for the alternative array initialiser:
var a1 = new int[3] { 1, 2, 3 }; // OK
var a2 = { 1, 2, 3 }; // Error: Cannot initialize an implicitly-typed variable with an array initializer
// BTW. You can omit the size
var a3 = new int[] { 1, 2, 3 }; // OK
With the alternative syntax you cannot specify the size, it's always inferred.
var a1 = new int[100]; // Array with 100 elements (all 0)
int[] a2 = { }; // Array with no elements
There is no difference in the compiled code between the two lines.
The second one is just a shortcut. Both statements have the same result. The shorter variant just wasn't available in early versions of C#.
The first one uses 3 as a array size explictly, the 2nd one size is inferred.
This might be work if you dont want to initialize the values.
There is no difference between this two array initialization syntaxes in terms how they will be translated by the compiler into IL (you can play with it at sharplab.io) and it is the same as the following one:
int[] thirdArray = new int[] { 1, 2, 3 };
The only difference comes when you are using those with already declared variable, i.e. you can use 1st and 3rd to assign new value to existing array variable but not the second one:
int[] arr;
arr = new int[3] { 1, 2, 3 }; // works
// arr = { 1, 2, 3 }; // won't compile
arr = new int[] { 1, 2, 3 }; // works
This question already has answers here:
How to unifiy two arrays in a dictionary?
(4 answers)
Closed 4 months ago.
I have two arrays (that are always going to have the same length). Something like
array1 = [ "a", "b", "c" ]
array2 = [ 1, 2, 3 ]
I'd like to know if there's a way to merge both arrays into a single JSON object in C# to something like
{
"a": 1,
"b": 2,
"c": 3
}
any help is appreciated.
It was that simple: Zip + ToDictionary before serialization.
using System.Text.Json;
using System.Text.Json.Serialization;
var array1 = new string[]{ "a", "b", "c" } ;
var array2 = new int[] { 1, 2, 3 };
var dict = array1
.Zip(array2, (a1,a2)=> (key:a1, value:a2))
.ToDictionary(k => k.key, v => v.value);
Console.WriteLine(JsonSerializer.Serialize(dict));
Zip takes two collections of the same size and creates a new one based on the result of a merge function (here, I used it to create tuples)
ToDictionary creates an enumerable to a dictionary structure.
Outputs:
{"a":1,"b":2,"c":3}
One note about this answer though: If you have two or more identical items in the first collection, this WILL throw an exception.
I'm working on a project. I've a situation here. I'm having arrays with similar names consider arr1, arr2, arr3, etc.
Now I know the array number which I'm supposed to use let it be 2. Is there any way in c# to make the array name dynamically through strings and use it.
Like in flash action script we can do
_root["arr"+i][0]
here i contains the array number to be used.
No - you cannot access variable names dynamically. You can use reflection to dynamically access properties, but not variables. I would use a List<int[]> like so:
List<int[]> arrList = new List<int[]> {arr1, arr2, arr3);
int[] arr = arrList[i-1]; // since lists and arrays use 0-based indexes
You can use a dictionary:
var dictionary = new Dictionary<string, int[]>();
dictionary.Add("array1", arr1);
dictionary.Add("array2", arr2);
dictionary.Add("array3", arr3);
var arr = dictionary[string.Format("array{0}", i)];
What you want is something what JavaScript or dynamic languages have, but their array types are rather associative arrays. To reach the functionality you want you can use Dictionary:
var arr1 = new int[] { 0, 1, 2, 3 };
var arr2 = new int[] { 0, 1, 2, 3 };
var arr3 = new int[] { 0, 1, 2, 3 };
var _root = new Dictionary<string, int[]>();
_root.Add("arr1", arr1);
_root.Add("arr2", arr2);
_root.Add("arr3", arr3);
for (int i = 1; i <= 3; i++)
{
int arrElem = _root["arr" + i][0];
}
Note the expression within the for loop, it's like what you were asking for.
use list for performing dynamic operations
As suggested in other answers the way to achieve the dynamism you're looking for is to put all of the arrays in a collection ( List<int[]> ) and then you can write more generalized code which operates on the contents of a given array without knowing which array it's operating on at compile time.
From: http://msdn.microsoft.com/en-us/library/2s05feca.aspx
Notice that you cannot omit the new operator from the elements initialization because there is no default initialization for the elements:
int[][] jaggedArray3 =
{
new int[] {1,3,5,7,9},
new int[] {0,2,4,6},
new int[] {11,22}
};
What does it mean?
Why is it ok to omit new in:
int[] arrSimp = { 1, 2, 3 };
int[,] arrMult = { { 1, 1 }, { 2, 2 }, { 3, 3 } };
but not possible in:
int[][,] arrJagg = {new int[,] { { 1, 1} }, new int[,] { { 2, 2 } }, new int[,] { { 3, 3 } } };
First off, what a coincidence, an aspect of your question is the subject of my blog today:
http://ericlippert.com/2013/01/24/five-dollar-words-for-programmers-elision/
You've discovered a small "wart" in the way C# classifies expressions. As it turns out, the array initializer syntax {1, 2, 3} is not an expression. Rather, it is a syntactic unit that can only be used as part of another expression:
new[] { 1, 2, 3 }
new int[] { 1, 2, 3 }
new int[3] { 1, 2, 3 }
new int[,] { { 1, 2, 3 } }
... and so on
or as part of a collection initializer:
new List<int> { 1, 2, 3 }
or in a variable declaration:
int[] x = { 1, 2, 3 };
It is not legal to use the array initializer syntax in any other context in which an expression is expected. For example:
int[] x;
x = { 1, 2, 3 };
is not legal.
It's just an odd corner case of the C# language. There's no deeper meaning to the inconsistency you've discovered.
In essence the answer is "because they (meaning the language designers) choose not to.To quote from Eric Lippert:
The same reason why every unimplemented feature is not implemented:
features are unimplemented by default. In order to become implemented
a feature must be (1) thought of, (2) designed, (3) specified, (4)
implemented, (5) tested, (6) documented and (7) shipped.
More technically there is a good reason to it and that's the definition of jagged arrays compared to 1-dimension and multi-dimension arrays.
A one or more dimension arrays can be expressed in plain English as a X dimension array of T where a jagged array has to be expressed as an Array of arrays of T. In the second case, there is a loose coupling between the inner array and the outer arary. That is, you can assign a new array to a position within the outer array whereas a x dimension array is fixed.
Now that we know that Jagged arrays are very different from multi-dimensional arrays in their implementation, we can also assume why there is a different level of integrated support for the 2. It's certainly not impossible to add support, just a question of demand and time.
(as a teaser, why only add support for jagged arrays? how about your own custom types?)
My following code has compile error,
Error 1 Cannot implicitly convert type 'TestArray1.Foo[,,*]' to 'TestArray1.Foo[][][]' C:\Users\lma\Documents\Visual Studio 2008\Projects\TestArray1\TestArray1\Program.cs 17 30 TestArray1
Does anyone have any ideas? Here is my whole code, I am using VSTS 2008 + Vista 64-bit.
namespace TestArray1
{
class Foo
{
}
class Program
{
static void Main(string[] args)
{
Foo[][][] foos = new Foo[1, 1, 1];
return;
}
}
}
EDIT: version 2. I have another version of code, but still has compile error. Any ideas?
Error 1 Invalid rank specifier: expected ',' or ']' C:\Users\lma\Documents\Visual Studio 2008\Projects\TestArray1\TestArray1\Program.cs 17 41 TestArray1
Error 2 Invalid rank specifier: expected ',' or ']' C:\Users\lma\Documents\Visual Studio 2008\Projects\TestArray1\TestArray1\Program.cs 17 44 TestArray1
namespace TestArray1
{
class Foo
{
}
class Program
{
static void Main(string[] args)
{
Foo[][][] foos = new Foo[1][1][1];
return;
}
}
}
EDIT: version 3. I think I want to have a jagged array. And after learning from the fellow guys. Here is my code fix, and it compile fine in VSTS 2008. What I want is a jagged array, and currently I need to have only one element. Could anyone review whether my code is correct to implement my goal please?
namespace TestArray1
{
class Foo
{
}
class Program
{
static void Main(string[] args)
{
Foo[][][] foos = new Foo[1][][];
foos[0] = new Foo[1][];
foos[0][0] = new Foo[1];
foos[0][0][0] = new Foo();
return;
}
}
}
thanks in advance,
George
Regarding version 2 of your code - unfortunately you can't specify jagged arrays in that way. Instead, you need to do:
Foo[][][] foos = new Foo[1][][];
foos[0] = new Foo[1][];
foos[0][0] = new Foo[1];
You have to populate each array separately, basically. Foo[][][] means "an array of arrays of arrays of Foo." An initialization statement like this is only capable of initializing one array at a time. With the rectangular array, you still end up with just a single (multi-dimensional) array, which is why new Foo[1,1,1] is valid.
If this is for real code by the way, I'd urge you to at least consider other design decisions. Arrays of arrays can be useful, but you can easily run into problems like this. Arrays of arrays of arrays are even nastier. There may be more readable ways of expressing what you're interested in.
Make up your mind :)
You either want:
Foo[,,] foos = new Foo[1, 1, 1];
or:
Foo[][][] foos = new Foo[1][1][1];
You are declaring a double-nested array (array of array of array) and assigning a three-dimensional array. Those two are definitely different. You can change your declaration to
Foo[,,] foos = new Foo[1,1,1]
if you want a truly three-dimensional array. Jagged arrays (the [][][] kind) are not that needed in C# as in, say, Java.
The simplest answer is to use
Foo[,,] foos = new Foo[2, 3, 4];
Which gives you a 3-dimensional array as a contiguous block of memory of 2*3*4=24 Foo's.
The alternative looks like :
Foo[][][] foos = new Foo[2][][];
for (int a = 0; a < foos.Length; a++)
{
foos[a] = new Foo[3][];
for (int b = 0; b < foos[a].Length; b++)
{
foos[a][b] = new Foo [4];
for (int c = 0; c < foos[a][b].Length; c++)
foos[a][b][c] = new Foo();
}
}
Although this jagged (= array of array) approach is a bit more work, using it is actually faster. This is caused by a shortcoming of the compiler that will always do a range check when accessing an element in the Foo[,,] case, while it is able to at least optimize for-loops that use the Length property in the Foo[][][] scenario.
Also see this question
These two different array declarations create very different things.
Let's look at simpler case:
Foo[,] twoDimensionArray = new Foo[5,5];
This array has two dimensions - you can think of it as a table. You need both axis in order to return anything:
Foo item = twoDimensionArray[2,3]
The indexes always have the same lengths - in this case 0-4.
A jagged array is actually an array of arrays:
Foo[][] jaggedArray = new Foo[5][];
jaggedArray[0] = new Foo[2];
jaggedArray[1] = new Foo[4];
...
If you only use one axis index it will return an array:
Foo[] oneRow = jaggedArray[3];
If you use both you make your selection from the sub-array:
Foo item = jaggedArray[3][2];
//would be the same as:
Foo item = oneRow[2];
Each of these sub-arrays can have a different length, or even not be populated.
Depends on whether you want them to be jagged or not:
//makes a 5 by 4 by 3 array:
string[,,] foos = new string[5,4,3];
http://msdn.microsoft.com/en-us/library/aa288453(VS.71).aspx
Oh and here is initializing values:
char[, ,] blah = new char[2, 2, 2] {
{{ '1', '2' }, { '3', '4' }},
{{ '5', '6' }, { '7', '8' }}
};
Note that this will not work:
Foo[][][] foos = new Foo[1][1][1];
Because you are using the jagged array syntax, which does not let you define the size of nested arrays. Instead use do this:
Foo[,,] foos = new Foo[1][1][1]; //1 by 1 by 1
or this
Foo[][][] foos = new Foo[1][][]; //1 array allowing two nested levels of jagged arrays
foos[0] = new Foo[1]; //for the first element, create a new array nested in it
foos[0][0] = new Foo[1]; //create a third level new array nested in it
If it means anything, for just the C# declaration:
int[,,] ary = new int[,,]
{
{ { 111, 112 }, { 121, 122 }, { 131, 132 } }
, { { 211, 212 }, { 221, 222 }, { 231, 232 } }
, { { 311, 312 }, { 321, 322 }, { 331, 332 } }
, { { 411, 412 }, { 421, 422 }, { 431, 432 } }
};
Array Initialization
int[, ,] array3D = new int[,,] { { { 1, 2, 3 }, { 4, 5, 6 } },
{ { 7, 8, 9 }, { 10, 11, 12 } } }
source: Multidimensional Arrays (C# Programming Guide)