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
Related
Here's an example of a solution I came up with
using System;
using System.Linq;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
int[] arr = new int[] { 1, 2, 2, 3, 3, 3, 4, 4, 4, 4 };
var countlist = arr.Aggregate(new Dictionary<int,int>(), (D,i) => {
D[i] = D.ContainsKey(i) ? (D[i] + 1) : 1;
return D;
})
.AsQueryable()
.OrderByDescending(x => x.Value)
.Select(x => x.Key)
.ToList();
// print the element which appears with the second
// highest frequency in arr
Console.WriteLine(countlist[2]); // should print 3
}
}
At the very least, I would like to figure out how to
Cut down the query clauses by at least one. While I don't see any redundancy, this is the type of LINQ query where I fret about all the overhead of all the intermediate structures created.
Figure out how to not return an entire list at the end. I just want the 2nd element in the enumerated sequence; I shouldn't need to return the entire list for the purpose of getting a single element out of it.
int[] arr = new int[] { 1, 2, 2, 3, 3, 3, 4, 4, 4, 4 };
var lookup = arr.ToLookup(t => t);
var result = lookup.OrderByDescending(t => t.Count());
Console.WriteLine(result.ElementAt(1).Key);
I would do this.
int[] arr = new int[] { 1, 2, 2, 3, 3, 3, 4, 4, 4, 4 };
int rank =2;
var item = arr.GroupBy(x=>x) // Group them
.OrderByDescending(x=>x.Count()) // Sort based on number of occurrences
.Skip(rank-1) // Traverse to the position
.FirstOrDefault(); // Take the element
if(item!= null)
{
Console.WriteLine(item.Key);
// output - 3
}
I started to answer, saw the above answers and thought I'd compare them instead.
Here is the Fiddle here.
I put a stopwatch on each and took the number of ticks for each one. The results were:
Orignal: 50600
Berkser: 15970
Tommy: 3413
Hari: 1601
user3185569: 1571
It appears #user3185569 has a slightly faster algorithm than Hari and is about 30-40 times quicker than the OP's origanal version. Note is #user3185569 answer above it appears his is faster when scaled.
update: The numbers I posted above were run on my pc. Using .net fiddle to execute produces different results:
Orignal: 46842
Berkser: 44620
Tommy: 11922
Hari: 13095
user3185569: 16491
Putting the Berkser algortihm slightly faster. I'm not entirely clear why this is the case, as I'm targeting the same .net version.
I came up with the the following mash of Linq and a dictionary as what you're looking for is essentialy an ordered dictionary
void Run()
{
int[] arr = new int[] { 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4 };
int[] unique = arr.Distinct().ToArray();
Dictionary<int, int> dictionary = unique.ToDictionary(k => k, v => 0);
for(int i = 0; i < arr.Length; i++)
{
if(dictionary.ContainsKey(arr[i]))
{
dictionary[arr[i]]++;
}
}
List<KeyValuePair<int, int>> solution = dictionary.ToList();
solution.Sort((x,y)=>-1* x.Value.CompareTo(y.Value));
System.Console.WriteLine(solution[2].Key);
}
I found similar topics, but I could not solve the problem I has reading them.
I want to do in C# the same thing like in C is array of pointers, but I do not want to use in C# pointers because it requires to use "unsafe".
How to build an array of " ref to int" that when I change any element of that array then I will also change that what it refs to at the same time the variable that it points to ( Like in C - array of pointers).
Best regards,
Chris
If performance is not a concern, than one common workaround is to use lambda to capture the access to value type variable:
Sample:
class GetSetPair<T>
{
public Func<T> Get {get;set;}
public Action<T> Set {get;set;}
}
var referencesToInt = new List<GetSetPair<int>>();
int value = 42;
referencesToInt.Add(new GetSetPair<int>{Get=()=>value, Set = v => value = v});
referencesToInt[0].Set(33);
Console.WriteLine(value); // 33
value = 22;
Console.WriteLine(referencesToInt[0].Get()); //22
Arrays are reference types, and therefore you can pass around references to that array. For example, given the following program:
public class Program
{
public static Random rnd = new Random();
public static int[] array2;
public static void Main()
{
int[] array = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
PrintArray(array);
array[4] = rnd.Next();
PrintArray(array);
ModArray(array, 2);
PrintArray(array);
array2 = array; //This makes array2 reference array1
ModArray(array2, 8); //Operate on the array2 reference
PrintArray(array); //Changes are reflected in array
PrintArray(array2); //And in array2
Console.ReadKey(true);
}
public static void PrintArray(int[] array)
{
foreach (var e in array)
Console.Write(e + ", ");
Console.WriteLine();
}
public static void ModArray(int[] array, int i)
{
array[i] = rnd.Next();
}
}
Will give the following output:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, <- Original
1, 2, 3, 4, 744477516, 6, 7, 8, 9, 10, <- Modified in Main
1, 2, 102109069, 4, 744477516, 6, 7, 8, 9, 10, <- Modified in ModArray
1, 2, 102109069, 4, 744477516, 6, 7, 8, 1776657318, 10, <- array, after modifying array2
1, 2, 102109069, 4, 744477516, 6, 7, 8, 1776657318, 10, <- array2
So in a sense, you can pass around a reference to the array, modify that reference, and have it reflected in all of its copies.
The caveat here is that anybody who "owns" a reference to the original array cannot reassign that array (or resize it). It can modify the elements of the array, but it can't make the original array point to a new instance (which is what happens when it is resized). Also, as Jon Skeet mentioned in his comment, the danger is that if you were doing this in a different method other than Main, if the array goes out of scope, what would happen to array2?
See Also:
Is int[] a reference type or a value type?
Are arrays or lists passed by default by reference in c#?
I have a class piece where I define each piece shape.
myShape.Add(new piece
{
Height = 3,
Width = 2,
Name = "3x2 L TopRight",
Size = 4,
Shape = new int[][] {
new int[] { 1, 0 },
new int[] { 1, 0 },
new int[] { 1, 1 }
}
});
But I create those shape by hand, now I reading the pieces in real time, so I create something like
List<int[]> virtualRow = new List<int[]>();
virtualRow.Add(new int[] { 1, 0 });
virtualRow.Add(new int[] { 1, 0 });
virtualRow.Add(new int[] { 1, 1 });
So how can I create Shape using virtualRow ?
I try something like
Shape = new int[][] { virtualRow.ToArray() }
But say
Cannot implicitly convert type 'int[][]' to 'int[]'
virtualRow.ToArray() is already an array of array of int values. You don't need to create a new array of array of ints and add this to it.
All you need is:
Shape = virtualRow.ToArray(),
virtualRow is a List of integer arrays, so to get an array of integer arrays you simply write:
Shape = virtualRow.ToArray();
...the return type of List.ToArray() being T[] as required.
Your code is in error because it attempts to add an int[][] to Shape instead of creating Shape as an int[][].
You want to do the following:
Shape = virtualRow.ToArray();
Since virtualRow is already a list of arrays. The ToArray function creates an int[][] object for your virtualRow, and all you need to do is store it to shape. What you were trying to do was create a matrix, within which was the result of the ToArray function. This way you are just storing the result of the function which gives you what you want.
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?)
Having just spent over an hour debugging a bug in our code which in the end turned out to be something about the Enumerable.Except method which we didn't know about:
var ilist = new[] { 1, 1, 1, 1 };
var ilist2 = Enumerable.Empty<int>();
ilist.Except(ilist2); // returns { 1 } as opposed to { 1, 1, 1, 1 }
or more generally:
var ilist3 = new[] { 1 };
var ilist4 = new[] { 1, 1, 2, 2, 3 };
ilist4.Except(ilist3); // returns { 2, 3 } as opposed to { 2, 2, 3 }
Looking at the MSDN page:
This method returns those elements in
first that do not appear in second. It
does not also return those elements in
second that do not appear in first.
I get it that in cases like this:
var ilist = new[] { 1, 1, 1, 1 };
var ilist2 = new[] { 1 };
ilist.Except(ilist2); // returns an empty array
you get the empty array because every element in the first array 'appears' in the second and therefore should be removed.
But why do we only get distinct instances of all other items that do not appear in the second array? What's the rationale behind this behaviour?
I certainly cannot say for sure why they decided to do it that way. However, I'll give it a shot.
MSDN describes Except as this:
Produces the set difference of two
sequences by using the default
equality comparer to compare values.
A Set is described as this:
A set is a collection of distinct
objects, considered as an object in
its own right