In C# I have three arrays, string[] array1, 2 and 3 and they all have differnt values. I would love to do what I can do in php which is:
$array = array();
$array[] .= 'some value';
Whats the equivalent way of doing this in C#?
In C#, you'd typically use a List<string> instead of string[].
This will allow you to write list.Add("some value") and will "grow" the list dynamically.
Note that it's easy to convert between a list and an array if needed. List<T> has a constructor that takes any IEnumerable<T>, including an array, so you can make a list from an array via:
var list = new List<string>(stringArray);
You can convert a list to an array via:
var array = list.ToArray();
This is only required if you need an array, however (such as working with a third party API). If you know you're going to work with collections that vary in size, it's often better to just always stick to List<T> and not use arrays.
You can create a list and add the array values to it and then convert that list back to array.
int[] array1 = { 1, 2, 3, 4, 5 };
int[] array2 = { 6, 7, 8, 9, 10 };
// Create new List of integers and call AddRange twice
var list = new List<int>();
list.AddRange(array1);
list.AddRange(array2);
// Call ToArray to convert List to array
int[] array3 = list.ToArray();
You could use dinamic lists List<string>. You can do
List<string> TotalList = array1.ToList();
Then you can TotalList.AddRange(array2) and so on....
List<T> or LINQ may be the easiest solutions, but you can also do it the old fashioned way:
// b1 is now 5 bytes
byte[] b1 = Get5BytesFromSomewhere();
// creating a 6-byte array
byte[] temp = new byte[6];
// copying bytes 0-4 from b1 to temp
Array.copy(b1, 0, temp, 0, 5);
// adding a 6th byte
temp[5] = (byte)11;
// reassigning that temp array back to the b1 variable
b1 = temp;
if you simply want to merge your arrays
use linq .Concat
array1 = array1.Concat(array2).Concat(array3).ToArray();
Easy with linq:
int[] array1 = { 1, 2, 3, 4, 5 };
int[] array2 = { 6, 7, 8, 9, 10 };
int[] array3 = { 3, 4 ,5, 9, 10 };
var result = array1
.Concat(array2)
.Concat(array3)
.ToArray();
Related
Is it possible to have an array which points to other arrays in C#?
double[] arr1 = new double[2]{1,2};
double[] arr2 = new double[2]{3,4};
double[] mergedArr = arr1 + arr2; //of course not working like that, but how to do it right?
So when I change a value in arr1 the value in the mergedArray automatically changes?
You could do something like this using Span<T> or Memory<T>
var arr = new double[]{1, 2, 3, 4};
var span1= arr.AsSpan(0, 2);
var span2= arr.AsSpan(2, 2);
span2[0] = 5;
// arr is now {1, 2, 5, 4}
Span<T> work kind of like a smart pointer that lets you refer to memory inside an array. But you have to start with the actual array, and create your spans from this, you cannot "merge" arrays, since they are different objects and will be placed in non-continous memory.
Note that Spans is very lightweight and cheap, but has some restrictions on how it can be used, Memory<T> is slightly less lightweight but removes some of the restrictions, I recommend reading the documentation to avoid any surprises.
Points to other arrays -> this is not possible I think. Not sure. You can copy arrays to new array.
double[] arr1 = new double[2]{1,2};
double[] arr2 = new double[2]{3,4};
double[] arr3 = new double[arr1.Length +arr2.Length];
arr1.CopyTo(arr3, 0);
arr2.CopyTo(arr3 , arr1.Length);
You should use IEnumerable, then you can use LINQ's Concat
IEnumerable<double> mergedArr = arr1.Concat(arr2);
This does not create a new object unless you call ToArray or ToList on it
I think you are asking for a jagged array
double[] arr1 = new double[] {1, 2};
double[] arr2 = new double[] {3, 4};
double[][] jaggedArr = new double[][] { arr1, arr2};
which can be accessed via jaggedArr[0][1] => first array (0 index) and second element (1 index).
This creates an array of arrays { {1 ,2}, {3, 4} }
You can manually fill in the array of arrays which gives you more flexibility. For example
double[][] jaggedArr = new double[2][];
jaggedArr[0] = arr1;
jaggedArr[1] = arr2;
Unless you want to create an array from the values of the two arrays concatenated together (one after the other). Then you do
double[] concatArr = arr1.Concat(arr2).ToArray();
This creates a single array with values {1,2,3,4}.
Consider the int array below of n elements.
1, 3, 4, 5, 7. In this example the second last item is 5. I want to get the number of elements in this array before the second last value. There are 3 elements before the second last element. I will store the result in an int variable to use later. We obviously take into account that the array will have more than two element all the time.
This array will have different size everytime.
How can I achieve this in the most simplistic way?
The answer will always be n-2, so a very quick solution is to use .Length property and to subtract 2.
You can use Range from C# 8:
int[] arr = new int[]{1, 3, 4, 5, 7};
int[] newArr = arr.Length>=2 ? arr[..^2] : new int[0];
This will return all elements except the last 2, or an empty array if the lenght is less than 2. If it is guaranteed that the array will always have more than 2 elements, then you can simplify:
int[] newArr = arr[..^2];
If you are only interested about the quantity of the numbers then .Length-2 is the best way as it was stated by others as well.
If you are interested about the items as well without using C# 8 features then you can use ArraySegment (1).
It is really powerful, like you can reverse the items without affecting the underlying array.
int[] arr = new int[] { 1, 3, 4, 5, 7 };
var segment = new ArraySegment<int>(arr, 0, arr.Length - 2);
var reversedSegment = segment.Reverse(); //ReverseIterator { 4, 3, 1 }
//arr >> int[5] { 1, 3, 4, 6, 7 }
Please bear in mind that the same is not true for Span (2).
var segment = new Span<int>(arr, 0, arr.Length - 2);
segment.Reverse();
//arr >> int[5] {4, 3, 1, 6, 7 }
There is a ReadOnlySpan, which does not allow to perform such operation as Reverse.
If you would need that then you have to manually iterate through that in a reversed order.
I'm hoping this will be fairly simple and down to my lack of knowledge as a beginner but I'm trying to see if an array of ints with two elements is in a List.
Int[] meh = {1,2};
List<int[]> list1 = new List<int[]>();
List1.Add(meh);
Int[] meh2 = {1,2};
If(List1.Contains(meh2))
{
Console.WriteLine(“Found it”);
}
From reading around I gather that the array wont be found as it's to do with how Lists compare objects by reference and not value ... all examples Ive found have been to find a single int within an array in a List but not the array as a whole.
Im vaguely aware that List.Find() may be useful here but again I cant see how to use LINQ for matching both elements in each array in the list.
Any help or pointers to reading material greatly appreciated.
Thanks in advance.
How about this
if(list1.Any(x => x.SequenceEqual(meh2)))
{
Console.WriteLine("Found it");
}
You can use Enumerable.SequenceEqual
that will return -1 if the sequence is not found
example:
var myArr = new int[] { 3, 3 };
List<int[]> ListOfArrays = new List<int[]>
{
new int[] { 0, 0 },
new int[] { 2, 2 },
new int[] { 1, 1 },
new int[] { 3, 3 }
};
var index = ListOfArrays.FindIndex(l => Enumerable.SequenceEqual(myArr, l));
Console.WriteLine("here: " + index);
Not sure what you want to achieve exactly. If list1 has an element [1, 2, 3] and you search for [1, 2], would that be a match, or do all elements have to match? Do they have to be in the same order? ...
Whatever you want to achieve exactly, you can do it with Any() and SequenceEqual()
int[] meh = {1, 2};
int[] meh2 = {1, 5};
var list1 = new List<int[]>() {meh, meh2};
if (list1.Any(x => x.SequenceEqual(new[] {1, 5})))
{
Console.WriteLine("Found it");
}
Also see this answer. It contains an example where both arrays are sorted first (ie ignoring the order of the elements in the array)
How can we delete all array elements between 2 numbers?
For example : The array is {2,6,3,6,8,2,7,2}
The user writes in two numbers, let's say 2 and 4.
That causes the program to delete every array elements between the 2nd and 4th position.
In this case, it deletes : 3,6,8
You cannot delete items from an array. But you can create a new array that contains only the items that you want to keep. In your case you can use the following:
int[] array = {2, 6, 3, 6, 8, 2, 7, 2};
array = array.Where((_, i) => i < 2 || i > 4).ToArray();
By the way, if you use a List instead of an array, then you can remove items. Consider the following example:
List<int> list = new List<int>() {2, 6, 3, 6, 8, 2, 7, 2};
for(int i = 4; i >= 2 ; i--)
{
list.RemoveAt(i);
}
For lists, you can use RemoveRange to do exactly that. It’s just that instead of the (inclusive) end index, you need to pass the number of elements you want to delete. So for inclusive indexes start and end it would look like this:
list.RemoveRange(start, end - start + 1);
For arrays, you cannot really do this as once created arrays have a fixed size. If you really need an array, you could create a list from the array, remove the items, and then create an array again using ToArray.
As Yacoub Massad mentioned in his answer: You cannot delete items from an array. But you can create a new array that contains only the items that you want to keep. In this case I would use linq, it's super easy:
int[] array = {2, 6, 3, 6, 8, 2, 7, 2};
int x = 2;
int y = 4;
var array1 = array.ToList()
.Take(x).Concat(array.ToList().Skip(x+y-1))
.ToArray();
foreach(var i in array1)
{
Console.Write(i);
Console.Write(',');
}
Result:
2,6,2,7,2,
DotNetFiddle Example
I am looking for fastest way to extend an array.
No matter if only for length + 1 or length + x it has to be the most fastest way.
Here is an example:
var arr = new int [200];
for(int = 0; i < 200; i++)
arr[i] = i;
And now I want to extend arr for 5 items beginning at index position 20.
var arr2 = new int [] { 999, 999, 999, 999, 999 }
How do I place arr2 inside arr by using most fast way in terms of performance?
The result shall look like this
0,1,2,3,4....20, 999, 999, 999, 999, 999, 21, 22, 23, 24....199
Create a new array which is the size you want, then use the static Array.Copy method to copy the original arrays into the new one.
You can't "extend" an array, you can only create a bigger one and copy the original into it.
Also, consider using List<int> or LinkedList<> instead of an array, unless you require extremely fine-grained control over what is in memory.
It is far easier to use List. But if you have to use arrays, you have to create new array of size 205 and copy values from both source arrays, since array size is constant.
Your best bet is to use something like List<int> rather than an array. But if you must use an array:
int[] arr1 = new int[200];
// initialize array
int[] arr2 = new int[]{999, 999, 999, 999, 999};
int targetPos = 20;
// resizes the array, copying the items
Array.Resize(ref arr1, arr1.Length + arr2.Length);
// move the tail of the array down
Buffer.BlockCopy(arr1, 4*targetPos, arr1, 4*(targetPos+arr2.Length), 4*(arr1.Length - targetPos));
// copy arr2 to the proper position
Buffer.BlockCopy(arr2, 0, 4*arr1.targetPos, 4*arr2.Length);
It might be faster to create a new array and copy the items, like this.
int[] newArray = new int[arr1.Length + arr2.Length];
// copy first part of original array
Buffer.BlockCopy(arr1, 0, newArray, 0, 4*targetPos);
// copy second array
Buffer.BlockCopy(arr2, 0, newArray, 4*targetPos, 4*arr2.Length);
// copy remainder of original array
Buffer.blockCopy(arr1, 4*targetPos, newArray, 4*(targetPos + arr2.Length), 4*(arr1.Length - targetPos));
// and replace the original array
arr1 = newArray;
Which version is faster will depend on where targetPos is. The second version will be faster when targetPos is small. When targetPos is small, the first version has to copy a lot of data twice. The second version never copies more than it has to.
BlockCopy is kind of a pain to work with because it requires byte offsets, which is the reason for all the multiplications by four in the code. You might be better off using Array.Copy in the second version above. That will prevent you having to multiply everything by 4 (and forgetting sometimes).
If you know how long the array will be dimension it to that length,
var ints = new int[someFixedLength];
If you have a vauge idea of the length, use a generic list.
var ints = new List<int>(someVagueLength);
both types implement IList but, the List type handles the redimensioning of the internal array is generically the "most fast" way.
Note: the initial .Count of the List will be 0 but, the internal array will be dimensioned to size you pass to to the constructor.
If you need to copy data between arrays, the quickest way is Buffer.BlockCopy, so from your example
Buffer.BlockCopy(arr2, 0, arr, sizeof(int) * 20, sizeof(int) * 5);
copies all 5 ints from arr2 into indecies 20, 21 ... 24 of arr.
there is no faster way to do this with c# (currently).
An answer showing timing benchmarks is given here: Best way to combine two or more byte arrays in C# . If you consider the "array you insert into " as arrays 1 and 3, and the "array to be inserted" as array 2, then the "concatenate three arrays" example applies directly.
Note the point at the end of the accepted answer: the method that is faster at creating yields an array that is slower to access (which is why I asked if you cared about speed to create, or access speed).
using System.Linq you can do the following to extend an array by adding one new object to it...
int[] intA = new int[] { 1, 2, 3 };
int intB = 4;
intA = intA.Union(new int[] { intB }).ToArray();
...or you can extend an array by adding another array of items to it...
int[] intA = new int[] { 1, 2, 3 };
int[] intB = new int[] { 4, 5, 6 };
intA = intA.Union(intB).ToArray();
...or if you don't care about duplicates...
int[] intA = new int[] { 1, 2, 3 };
int[] intB = new int[] { 4, 5, 6 };
intA = intA.Concat(intB).ToArray();