Generic Function: Cast T[] to Complex[] - c#

I need a function that works on any either real-valued or complex-valued array.
However, for the function itself, it is very convenient to work on a Complex[]-Array. Therefore I want to typecast any array which is not of type Complex[] (e.g. double[] or byte[] or int[]...) to Complex[].
I thought this might be a nice exercise for myself to write a small generic function:
private static Complex[] convertArrayToComplex<T>(T[] inpArr)
{
if (typeof(T) != typeof(Complex[]))
{
Complex[] inpArrC = new Complex[inpArr.Length];
for (int k = 0; k < inpArr.Length; k++)
{
inpArrC[k] = new Complex((double)(object)inpArr[k], 0);
}
return inpArrC;
} else
{
return inpArr; // Compiler-Error is here
}
}
Of course this does not work: I get the Compiler-Error telling me, that T[] cannot implicitly casted to Complex[]. I do understand this, but I do not see a way to achieve my goal in an elegant fashion.
Constraints: I know that inpArr is a numeric Array.

You can know the type is equal, but you still have to convince the compiler. Also, I would make the code clearer by using is instead of type checking:
private static Complex[] convertArrayToComplex<T>(T[] inpArr)
{
if (inpArr is Complex[])
{
return (Complex[])(object)inpArr;
}
Complex[] inpArrC = new Complex[inpArr.Length];
for (int k = 0; k < inpArr.Length; k++)
{
inpArrC[k] = new Complex(Convert.ToDouble(inpArr[k]), 0);
}
return inpArrC;
}

Related

C# Generic method for random number generation

I see that there is a similar question for C++. Does anyone know why this method works when the method is non-generic, but as soon as I make it generic, the random number portion of code fails?
Error: Cannot implicitly convert type int to 'T'. If I can't use generics, I will have to rewrite the same function over and over for each different length of array.
public void fillGenericArray<T>(T[] inputArray) where T : IComparable
{
var randomNumb1 = new Random();
for (int i = 0; i < inputArray.Length - 1; i++)
{
Console.WriteLine($"{inputArray[i] = randomNumb1.Next(1, 501)},");
}
}
I had to look twice at this, but here's the issue:
Because inputArray is an 'array of type T'
then even though i is an int the expression
inputArray[i]
returns a type T not a type int.
And so, conversely, a type T must be assigned to it.
A generic method like this might achieve your goal:
public static void fillGenericArray<T>(T[] inputArray)
{
for (int i = 0; i < inputArray.Length; i++)
{
// Where T has a CTor that takes an int as an argument
inputArray[i] = (T)Activator.CreateInstance(typeof(T), Random.Next(1, 501));
}
}
(Thanks to this SO post for refreshing my memory about instantiating T with arguments.)
You could also use Enumerable.Range() to get the same result without writing a method at all:
// Generically, for any 'SomeClass' with a CTor(int value)
SomeClass[] arrayOfT =
Enumerable.Range(1, LENGTH).Select(i => new SomeClass(Random.Next(1, 501)))
.ToArray();
(Slightly Modified with help from this SO post) - see the answer using Enumerable.Range().
Here is a test runner:
class Program
{
static Random Random { get; } = new Random();
const int LENGTH = 10;
static void Main(string[] args)
{
Console.WriteLine();
Console.WriteLine("With a generic you could do this...");
SomeClass[] arrayOfT;
arrayOfT = new SomeClass[LENGTH];
fillGenericArray<SomeClass>(arrayOfT);
Console.WriteLine(string.Join(Environment.NewLine, arrayOfT.Select(field=>field.Value)));
Console.WriteLine();
Console.WriteLine("But perhaps it's redundant, because Enumerable is already Generic!");
arrayOfT = Enumerable.Range(1, LENGTH).Select(i => new SomeClass(Random.Next(1, 501))).ToArray();
Console.WriteLine(string.Join(Environment.NewLine, arrayOfT.Select(field => field.Value)));
// Pause
Console.WriteLine(Environment.NewLine + "Any key to exit");
Console.ReadKey();
}
public static void fillGenericArray<T>(T[] inputArray)
{
for (int i = 0; i < inputArray.Length; i++)
{
inputArray[i] = (T)Activator.CreateInstance(typeof(T), Random.Next(1, 501));
}
}
class SomeClass
{
public SomeClass(int value)
{
Value = value;
}
public int Value { get; set; }
}
}
Clone or Download this example from GitHub.
There is no reason to use generics. Just replace T with int and you will have function that does what you want (based on your question and comment below it).
EDIT: From your comment it seems you misunderstand the purpose of generics. The non-generic function WILL work for all lengths of the array.
And to answer why the change to generics fails. You are trying to assign int to generic type T which can be anything and compiler will not allow such a cast.

Cannot convert from void to bool when trying to use an array in my reverse function

Just as the heading states, I am trying to reverse a float array with my own reverse function.
The reverse function must not return a variable. The logic of the program may be off, so I am probably approaching this wrong.
Now the error I get is that it cannot convert from void to bool.
public static void reverse(float[] floatArr)
{
for (int i = 0; i < floatArr.Length; i++)
{
Console.WriteLine(floatArr[i]);
}
for (int i = 0; i < floatArr.Length / 2; i++)
{
float tmp = floatArr[i];
floatArr[i] = floatArr[floatArr.Length - i - 1];
floatArr[floatArr.Length - i - 1] = tmp;
}
}
static void Main(string[] args)
{
float[] floatArr = new float[5] { 5.6F, 6.4F, 4.2F, 3.6F, 8.4F };
Console.WriteLine(reverse(floatArr)); // cannot convert from void to bool
}
I know that I could fix this by having the reverse function be a float function and thus returning a float, but question stated that it must not return a value.
You are trying to print a function which returns type is void.
Console.WriteLine(reverse(floatArr)); // cannot convert from void to bool -> this is correct error
You should first call reverse(floatArr) and if the intention to print then you should loop on array to print the values. like as follows:
reverse(floatArr);
foreach(var val in floatArr)
{
Console.WriteLine(val);
}
This will print the values in different lines on console. If you want to print all values in one line then use the below line (credit to #LeonidVasilyev)
Console.WriteLine(string.Join(",", floatArr));

C# - HackerRank simpleArraySum

Now, I may get negative points because perhaps somewhere in vast internet there is already an answer to this but I tried to look for it and I simply couldnt find it.
The gist of the problem is that HackerRanks wants you to create an array with a size decided by the user, then have the user add its values (integers) and finally have the program sum its values.
There are plenty of ways to do it and I already know how to but my problem is that I just can't understand Hackerrank's code sample in C# it gave me. I commented the parts I don't understand, which is most of it:
static int simpleArraySum(int n, int[] ar) {
// Complete this function
int sum = 0;
foreach( var item in ar){
sum += item;
}
return sum;
}
static void Main(String[] args) {
//I know what this does
int n = Convert.ToInt32(Console.ReadLine());
//I am lost here, just why create a string array and add the split method?
string[] ar_temp = Console.ReadLine().Split(' ');
//I dont understand here neither, what is it converting? What is the parse for?
int[] ar = Array.ConvertAll(ar_temp,Int32.Parse);
//Why send the n when all you need is the array itself?
int result = simpleArraySum(n, ar);
Console.WriteLine(result);
}
I know some people hate HackerRank, and honestly, I do too but it does gives me some nice ways to test my limited skills in coding with c# and testing my logic. So, if there are better sites that helps you test your logic as a CS please share them with me.
Here is the code I made to solve this problem in Visual Studio but for some stupid reason Hackerrank wont accept it unless I make custom inputs:
//This code can be potentially shorter using the code commented further below.
//For practice's sake, it was made longer.
static int simpleArraySum(int[] arr_temp)
{
int total = 0;
foreach (var item in arr_temp)
{
total += item;
}
return total;
}
static void Main(String[] args)
{
int n = Convert.ToInt32(Console.ReadLine());
int[] arr_temp = new int[n];
for (int i = 0; i < n; i++)
{
arr_temp[i] = Convert.ToInt32(Console.ReadLine());
}
int result = simpleArraySum(arr_temp);
//int result = arr_temp.Sum();
Console.WriteLine(result);
Console.ReadLine();
}
You need to convert to string array since if you're on the main method, all it gets are string values from the argument list. To get the sum then you need to convert the string into a usable number / integer.
I agree that it doesn't make sense to send the first argument n in simpleArraySum because n is simply unused.
as for the part int[] ar = Array.ConvertAll(ar_temp,Int32.Parse); it simply tries to take in all the integers into the array. It is also risky because if you accidentally pass in a string then it will throw an error i.e. pass in "3 4 1 f" <- f will throw an exception, unless this is the desired behaviour.
Personally I think the main method should not be interested in getting involved too much with the data, the heavy lifting should be done in the methods. The better version perhaps would be to modify simpleArraySum and refactor that line in like:
static int simpleArraySum(string input)
{
String[] fields = input.Split(null);
List<int> vals = new List<int>();
foreach (string i in fields)
{
var j = 0;
if (Int32.TryParse(i, out j)) vals.Add(j);
}
int sum = 0;
foreach (var item in vals)
{
sum += item;
}
return sum;
}
I introduced the use of generic list because it's more readable if not cleaner, although the use of List might look overkill to some programmers and might not be as light weight as just using an array, hence on the other hand you can easily stick to using arrays except that it needs to be initialized with the length i.e. int[] vals = new int[fields.Length]; Roughly:
static int simpleArraySum(string input)
{
String[] fields = input.Split(null);
int[] vals = new int[fields.Length];
for (int i = 0; i < fields.Length; i++)
{
var j = 0;
if (Int32.TryParse(fields[i], out j)) vals[i] = j;
}
int sum = 0;
foreach (var item in vals)
{
sum += item;
}
return sum;
}
here my code i hope that helps
static int simpleArraySum(int[] ar,int count) {
if (count > 0 && count <= 10000)
{
if (count == ar.Length)
{
if (!ar.Any(item => (item < 0 || item >= 10000)))
{
return ar.Sum();
}
}
}
return 0;
}
and in main
int arCount = Convert.ToInt32(Console.ReadLine());
int[] arr = Array.ConvertAll(Console.ReadLine().Split(' '), arTemp => Convert.ToInt32(arTemp));
int result = simpleArraySum(arr, arCount);
Console.WriteLine(result);
since Array.ConvertAll() takes a string and convert it to one type array
int or float for example
For users still looking for a 100% C# solution: In above mentioned coding websites do not modify the main function. The aim of the test is to complete the function via the online complier.
using System.Linq;
public static int simpleArraySum(List<int> ar)
{
int sum = ar.Sum();
return sum;
}

How do we index through an input array to a lambda expression

I am pretty new to lambda expressions and am trying to write a simple program here to understand the use of Func<> and can't understand why I cannot loop through an input array using indexing?
class Program
{
static void Main(string[] args)
{
int[] array = new int[4];
array[0] = -1; array[1] = 2; array[2] = 3; array[3] = 8;
Func<Array, int> DoSomething = inputarray =>
{
for (int i = 0; i < inputarray.Length; i++)
{
if (inputarray[i] > inputarray[i + 1])
{
//;
}
}
return 1;
};
}
}
This gives an error saying
cannot apply indexing with [] to an expression of type Array
How do I resolve this? Basically, how would I loop through my input array?
A System.Array is the base class of all arrays like an int[]. It implements also IList which allows to access items by index, but the Item property is implemented as an explicit interface member implementation. It can be used only when the Array instance is cast to an IList interface:
var list = (System.Collections.IList)inputarray;
Now you can use the indexer but it will return objects not ints, so you can't use following without casting because objects can't be compared with >:
if (list[i] > list[i + 1])
{
//;
}
I guess you want to use an int[]:
Func<int[], int> DoSomething = inputarray =>
// ...
You need to provide a type for the Array in the example you show.
try:
Func<int[], int> DoSomething
instead.

Use of unassigned out parameter, c#

I have very simple problem.
I made a very simple function for you to demonstrate my problem.
static void Main(string[] args)
{
double[,] mydouble = new double[1, 4];
mynewMatrix(out mydouble);
}
public static void mynewMatrix(out double[,] d)
{
for (int i = 0; i < 4; i++)
d[0, i] = i;
}
Error:
Use of unassigned out parameter 'newMAt' The out parameter 'newMAt'
must be assigned to before control leaves the current method
I don't know where is problem.
If the array is defined OUTSIDE of the function, you should use a ref (or nothing, considering the array is a reference type). out means the parameter will be initialized in the function before it returns. Some examples of use:
static void Main(string[] args)
{
double[,] mydouble;
mynewMatrix(out mydouble);// call of method
double[,] mydouble2 = new double[1, 4];
mynewMatrix2(mydouble2);// call of method
// useless for what you want to do
mynewMatrix3(ref mydouble2);// call of method
}
public static void mynewMatrix(out double[,] d)
{
d = new double[1, 4];
for (int i = 0; i < 4; i++)
{
d[0, i] = i;
}
}
public static void mynewMatrix2(double[,] d)
{
for (int i = 0; i < 4; i++)
{
d[0, i] = i;
}
}
// useless for what you want to do
public static void mynewMatrix3(ref double[,] d)
{
for (int i = 0; i < 4; i++)
{
d[0, i] = i;
}
}
I'll add that if you don't know what is the difference between ref and out you could read Difference between ref and out parameters in .NET
In c# there are two very similar keywords, ref and out.
Both of them pass values by reference, but the difference is:
When you use ref the compiler will require you to assign your variable prior to calling the method.
When using out it will not require this. This means that you will not be able to assume that the parameter has already been populated. You will not be able to read its value inside the method.
To illustrate the problem, just imagine what would happen if someone else wrote this code to call your method:
double[,] myUnassignedDouble;
mynewMatrix(out myUnassignedDouble);
Clearly the variable will never be assigned, which is bad.
This leaves you with three options:
Assign the variable each time you call the method and use void mynewMatrix(ref double[,] d)
Assign the variable once, inside your method and use void mynewMatrix(out double[,] d)
Assign the variable each time you call the method and use void mynewMatrix(double[,] d)
The third option will work because so far you don't seam to need to reassign your variable. Obviously that might change as your code becomes more complicated. I assume you did have your reasons for using out in the first place?
The error message is clear - you need to assign a value to your out parameter inside your method:
public static void mynewMatrix(out double[,] d)
{
d = new double[1, 4];
for (int i = 0; i < 4; i++)
{
d[0,i]=i;
}
}
The assignment you made outside the method has no effect. Just write this:
static void Main(string[] args)
{
double[,] mydouble;
mynewMatrix(out mydouble);
}
You are assigning values to the elements of your array parameter, but you have to assign y value to the array itself because its defined as out:
d = new double[1, 4];

Categories

Resources