Pass array to function from specific index in C# .Net - c#

I am new to C# (previously working on C++), I used to pass array to function with specific index. Here is the code in C++,
void MyFunc(int* arr) { /*Do something*/ }
//In other function
int myArray[10];
MyFunc(&myArray[2]);
Can I do something like this in C# .Net* ?*

As Array is Enumerable, you can make use of LINQ function Skip.
void MyFunc( int[] array ){ /*Do something*/ }
int[] myArray = { 0, 1, 2, 3, 4, 5, 6 }
MyFunc( myArray.Skip(2) );

The linq version is my preferred one. However it will prove to be very very inefficient.
You could do
int myArray[10];
int mySlice[8];
Array.Copy(myArray, 2, mySlice, 0);
and pass mySlice to the function

.NET has the System.ArraySegment<T> structure which addresses this exact use-case.
But I’ve never actually seen this structure used in code, with good reasons: it doesn’t work. Notably, it doesn’t implement any interfaces such as IEnumerable<T>. The Linq solution (= using Skip) is consequently the best alternative.

Probably the most simple way to do this is:
public void MyFunction(ref int[] data,int index)
{
data[index]=10;
}
And call it by this way:
int[] array= { 1, 2, 3, 4, 5 };
Myfunction(ref array,2);
foreach(int num in array)
Console.WriteLine(num);
This will print 1,2,10,4,5

public void MyFunc(ref int[] arr)
{
// Do something
}
int[] myArray = .... ;
MyFunc(ref myArray);
See here for more information on ref!

Related

C# CollectionAssert.Contains (int[][], int[]) does not pass

The function I want to test returns an int[][] aaiCluster1 with data
aaiCluster1[0] = int[] { 1, 2 }
aaiCluster1[1] = int[] { 0 }
so I test using
CollectionAssert.AreEqual (aaiCluster1[0], new int[] { 1, 2 });
CollectionAssert.AreEqual (aaiCluster1[1], new int[] { 0 });
But the order of the int[] is not important and may change, so I rather want to test
CollectionAssert.Contains (aaiCluster1, new int[] { 1, 2 });
but this fails.
Is this command not able to evaluate the content of the array?
Any ideas for a suitable workaround, that does not require additional helper functions?
edit
I have to clarify:
it's about testing whether a jagged array contains another simple array nested in it.
What else must I explain??
edit #2
2 answers suggesting CollectionAssert.AreEquivalent were given already and have been deleted again, because AreEquivalent is not what I'm looking for... it does not work here.
1 answer suggesting Sequence.whatever was given, and it's even more wrong.
edit #3
I reverted Igor's changes to my question, because I feel they too much alter the meaning. However, I think his words are a good alternative describtion, so here is his text:
So I test using
CollectionAssert.AreEqual(new int[] { 1, 2 }, aaiCluster1[0]);
CollectionAssert.AreEqual(new int[] { 0 }, aaiCluster1[1]);
But the order in aaiCluster1 (actual) is not known so the above tests could fail as soon as the returned order in aaiCluster1 changes.
Question
How can I call something similar to this
CollectionAssert.AreEqual(new int[] { 1, 2 }, aaiCluster1);
// CollectionAssert.AreEqual(ICollection<T> expected, ICollection<ICollection<T>> actual);
where all arrays in aaiCluster1 are evaluated against the expected parameter new int[] { 1, 2 } and the assert passes if there is at least one contained array that is found to be Equal to the expected?
aaiCluster1.ContainsArray(new int[] { 1, 2 });
static class Extensions
{
public static bool ItemsEqual<TSource>(this TSource[] array1, TSource[] array2)
{
if (array1 == null && array2 == null)
return true;
if (array1 == null || array2 == null)
return false;
return array1.Count() == array2.Count() && !array1.Except(array2).Any();
}
public static bool ContainsArray<TSource>(this TSource[][] array1, TSource[] array2)
{
return array1.Any(x => x.ItemsEqual(array2));
}
}
If you want to make sure the on set fully contains another you can just use linq, Assuming there are no duplicates you can do this:
Assert.IsTrue(new int[] { 1, 2 }.Except(aaiCluster1[0]).Count() == 0);

Pass a List to a params parameter

Is there was a way to pass a List as an argument to a params parameter? Suppose I have a method like this:
void Foo(params int[] numbers)
{
// ...
}
This way I can call it by passing either an array of ints or ints separated by commas:
int[] numbers = new int[] { 1, 5, 3 };
Foo(numbers);
Foo(1, 5, 3);
I wanted to know if there is a way to also be able to pass a List as an argument (without having to convert it to an array). For example:
List<int> numbersList = new List<int>(numbers);
// This won't compile:
Foo(numbersList);
No
Sadly, that's the answer. No, there is not. Not without converting it to an array (for example with .ToArray()).
You would want to change Foo to accept something other than params int[] to do this.
void Foo(IEnumerable<int> numbers) {
}
This would allow you to pass in either an int[] or a List<int>
To allow both ways, you could do this:
void Foo(params int[] numbers) {
Foo((IEnumerable<int>)numbers);
}
void Foo(IEnumerable<int> numbers) {
//Do the real thing here
}
If able to change the existing code, you could always create an overload that accepts a List and passes it to the params method.
void Foo(params int[] numbers)
{
// ...
}
void Foo(IList<int> numbers) => Foo(numbers.ToArray());

Unpacking an array into method arguments

As you know C# supports variadic methods through the params keyword:
int Add(params int[] xs) {
return xs.Sum();
}
Which can then be called with any number of arguments you like:
Add(1);
Add(1, 2);
Add(1, 2, 3);
But say I want to call Add using an array of ints1. Is this possible and how (preferably without reflection)? I tried the following but they gave syntax errors (the syntax was pure guessing):
var xs = new[] { 1, 2, 3 };
Add(xs...); // doesn't work; syntax error
Add(params xs); // doesn't work; syntax error
1 My actual use-case is different but I thought this example would be less complicated.
Your method needs a return type:
int Add(params int[] xs) {
return xs.Sum();
}
And to call it with an array you just use the ordinary syntax for method calls:
int[] xs = new[] { 1, 2, 3 };
var result = Add(xs);
The params keyword basically just allows you to take advantage of a little syntactic sugar. It tells the compiler that when it sees
Add(1, 2, 3);
It should convert that to
Add(new int[] { 1, 2, 3});
So to do this from your code, you don't have to do anything special.
int[] parameters = new int[] { ... }
results = Add(parameters);
See the documentation for more details.
As far as I know, you can just call it with an array like you would a normal method:
Add(xs);
Nothing fancy, no params keyword on the method call, no dots.
static void Main(string[] args)
{
int[] tmp = {1, 2};
var sum = Add(tmp);
}
public static int Add(params int[] xs)
{
return xs.Sum();
}
Should work just fine..
If it's anything like Java, you can just call the method with the array as an argument.
This feature is also what makes varargs dangerous, especially if one of the vararg types is also an array...

Initializing an array of a certain type using another array (C#)

This is my question:
Let's say I have a class with such a constructor:
Class A {
private int i;
public A(int new_i) {
i = new_i;
}
}
Can I initialize an array of A with an array of int?
If so, how can I do it?
I was thinking something like:
int[] b = new int[5] { 0,1,2,3,4};
A[] a;
a = new A[](b);
Thanks!
var a = Array.ConvertAll(b, item => new A(item));
The advantage here is that it will be created with the right size, without any intermediate steps - plus it works without LINQ.
In C# 2.0 it is a bit uglier - the following is identical:
A[] a = Array.ConvertAll<int,A>(b,
delegate(int item) { return new A(item); });
The combination of var, lambdas, and improved generic type inference really shine for C# 3.0 here.
You could use LINQ:
int[] b = new int[5] { 0, 1, 2, 3, 4 };
A[] a = b.Select(x => new A(x)).ToArray();

Return a subset of Array using index C#

What is the best way to return a subset of a C# array given a fromIndex and toIndex?
Obviously I can use a loop but are there other approaches?
This is the method signature I am looking to fill.
public static FixedSizeList<T> FromExisting(FixedSizeList<T> fixedSizeList, Int32 fromIndex, Int32 toIndex)
FixedSizeList internal implementation is
private T[] _Array;
this._Array = new T[size];
myArray.Skip(fromIndex).Take(toIndex - fromIndex + 1);
EDIT:
The result of Skip and Take are IEnumerable and the count will be zero until you actually use it.
if you try
int[] myArray = {1, 2, 3, 4, 5};
int[] subset = myArray.Skip(2).Take(2).ToArray();
subset will be {3, 4}
List Already has a CopyTo Method which should do what you want.
http://msdn.microsoft.com/en-us/library/3eb2b9x8.aspx
This is the Signature of the method:
public void CopyTo( int index, T[] array, int arrayIndex, int count )
Array.Copy will do what you want.

Categories