How can I copy a part of an array to another array?
Consider I'm having
int[] a = {1,2,3,4,5};
Now if I give the start index and end index of the array a it should get copied to another array.
Like if I give start index as 1 and end index as 3, the elements 2, 3, 4 should get copied in the new array.
int[] b = new int[3];
Array.Copy(a, 1, b, 0, 3);
a = source array
1 = start index in source array
b = destination array
0 = start index in destination array
3 = elements to copy
See this question. LINQ Take() and Skip() are the most popular answers, as well as Array.CopyTo().
A purportedly faster extension method is described here.
int[] a = {1,2,3,4,5};
int [] b= new int[a.length]; //New Array and the size of a which is 4
Array.Copy(a,b,a.length);
Where Array is class having method Copy, which copies the element of a array to b array.
While copying from one array to another array, you have to provide same data type to another array of which you are copying.
Note: I found this question looking for one of the steps in the answer to how to resize an existing array.
So I thought I would add that information here, in case anyone else was searching for how to do a ranged copy as a partial answer to the question of resizing an array.
For anyone else finding this question looking for the same thing I was, it is very simple:
Array.Resize<T>(ref arrayVariable, newSize);
where T is the type, i.e. where arrayVariable is declared:
T[] arrayVariable;
That method handles null checks, as well as newSize==oldSize having no effect, and of course silently handles the case where one of the arrays is longer than the other.
See the MSDN article for more.
In C# 8+ you can use ranges.
int a[] = {1,2,3,4,5};
int b[] = a[1..4]; // b = [2,3,4];
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-8.0/ranges
In case if you want to implement your own Array.Copy method.
Static method which is of generic type.
static void MyCopy<T>(T[] sourceArray, long sourceIndex, T[] destinationArray, long destinationIndex, long copyNoOfElements)
{
long totaltraversal = sourceIndex + copyNoOfElements;
long sourceArrayLength = sourceArray.Length;
//to check all array's length and its indices properties before copying
CheckBoundaries(sourceArray, sourceIndex, destinationArray, copyNoOfElements, sourceArrayLength);
for (long i = sourceIndex; i < totaltraversal; i++)
{
destinationArray[destinationIndex++] = sourceArray[i];
}
}
Boundary method implementation.
private static void CheckBoundaries<T>(T[] sourceArray, long sourceIndex, T[] destinationArray, long copyNoOfElements, long sourceArrayLength)
{
if (sourceIndex >= sourceArray.Length)
{
throw new IndexOutOfRangeException();
}
if (copyNoOfElements > sourceArrayLength)
{
throw new IndexOutOfRangeException();
}
if (destinationArray.Length < copyNoOfElements)
{
throw new IndexOutOfRangeException();
}
}
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
C# beginner here...
I have
int[] numbers = new int[10];
I would like to add 50 numbers to this array. Once the array is full, the first added number will be removed and the new number will be added. I would like to display the last added number on the top of the array. Such as
[5,4,3,2,1...]
not
[1,2,3,4,5,...]
How can I achieve this?
Thanks in advance
This is what I have tried
....
dataArray = new int[10];
....
Queue<int> numbers = new Queue<int>();
....
if (numbers.Count == 10)
{
numbers.Dequeue();
}
numbers.Enqueue(i);
numbers.CopyTo(dataArray, numbers.Count);
I keep getting " Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection" error
Array.Copy provides good performance for what you're trying to accomplish.
int[] newArray = new int[10];
newArray[0] = 4; // new value
Array.Copy(numbers, 0, newArray, 1, numbers.Length - 1);
Be careful with array lengths though with this as any bound issues with throw exceptions.
I think you should be using queue and then you can convert it into array if you want
class Program
{
static void Main(string[] args)
{
const int CAPACITY = 10;
Queue<int> queue = new Queue<int>(CAPACITY);
for (int i = 0; i < 50; i++)
{
if (queue.Count == CAPACITY)
queue.Dequeue();
queue.Enqueue(i);
}
queue.ToArray();
Console.WriteLine(queue.Count);
Console.ReadKey();
}
}
Take a look at the generic Queue class, that has the functionality that you are looking for with FILO structure. Doing this just with arrays...
int[] numbers=new int[50];
for(int i=0; i<numbers.length; i++) numbers[i]=i;
//fill the array with 1, 2, 3, 4...
//To reverse this order, swap elements in reverse
//numbers.length-1 is the last index of the array
// j<numbers.length/2,each time you swap you change two values, so only done half the length of the array
for(int j=numbers.length-1; j>numbers.length/2; j--) swap(numbers, j, numbers.length-j);
//swaps the values of different indexes in the array
void swap(int[] array, int index1, int index2) {
int temp=array[index1];
array[index1}=array[index2];
array[index2}=temp;
}
This should reverse the arrays
I have an Array variable. I can use the Rank property to get the number of dimensions and I know that you can use a foreach to visit each element as if the array was flattened. However, I wish to modify elements and change element references. I cannot dynamically create the correct number of for loops and I cannot invalidate an enumerator.
EDIT
Thanks for the comments, sorry about the previous lack of clarity at the end of a long tiring day. The problem:
private void SetMultiDimensionalArray(Array array)
{
for (int dimension = 0; dimension < array.Rank; dimension++)
{
var len = array.GetLength(dimension);
for (int k = 0; k < len; k++)
{
//TODO: do something to get/set values
}
}
}
Array array = new string[4, 5, 6];
SetMultiDimensionalArray(array);
Array array = new string[2, 3];
SetMultiDimensionalArray(array);
I had another look before reading this page and it appears all I need to do is create a list of integer arrays and use the overloads of GetValue and SetValue -
Array.GetValue(params int[] indices)
Array.SetValue(object value, params int[] indices)
Everything seems clear now unless someone can suggest a superior method. svick has linked to this so I will accept this answer barring any further suggestions.
It's hard to tell what exactly do you need, because your question is quite unclear.
But if you have a multidimensional array (not jagged array) whose rank you know only at runtime, you can use GetValue() to get the value at specified indices (given as an array of ints) and SetValue() to set it.
I need to find items count in the C# array which type is integer.
What I mean is;
int[] intArray=new int[10]
int[0]=34
int[1]=65
int[2]=98
Items count for intArray is 3.
I found the code for strArray below but It doesn't work for int arrays.
string[] strArray = new string[50];
...
int result = strArray.Count(s => s != null);
Well, first you have to decide what an invalid value would be. Is it 0? If so, you could do this:
int result = intArray.Count(i => i != 0);
Note that this only works because, by default, elements of an int array are initialized to zero. You'd have to fill the array with a different, invalid value beforehand if 0 ends up being valid in your situation.
Another way would be to use a nullable type:
int?[] intArray = new int?[10];
intArray[0] = 34;
intArray[1] = 65;
intArray[2] = 98;
int result = intArray.Count(i => i.HasValue);
While itsme86 provided you a good answer to your actual question, I suspect you may be better off reconsidering how you write this entirely.
If this is your goal, I would recommend thinking about this differently. Instead of allocating a fixed size array, and only assigning specific values to it, you might want to consider using a List<int>:
List<int> intList = new List<int>();
intList.Add(34);
intList.Add(65);
intList.Add(98);
The number of items will always be intList.Count, and you can add as many items as you wish this way, without worry about the "allocated size", since the list will automatically grow as needed. It also won't provide you bad results if you add 0 to the list as an actual value, where counting non-zero elements will not count a zero if it's a valid value.
Note that you can also access the items by index, just like you do with an array:
int secondValue = intList[1]; // Access like you do with arrays
int[] intArray=new int[3] // Edit: Changed this to 3 to make my answer work. :)
int[0]=34
int[1]=65
int[2]=98
int count = intArray.Length; // <-- Is this what you're after?
Edit:
Ahem. As was so humbly pointed out to me, Length will return the total number of elements in the array, which in your example would have been 10. If you are looking for the number of non-zero elements in the array, you should do as suggested in some of the other answers.
When you initialize an integer array without specifying any values, C# assigns a value of zero to every element. So if zero isn't a valid value for your array, you could always test for that.
Alternatively, you could initialize the elements of your array to some value that is invalid in your context (ie if negative numbers aren't valid, initialize to -1), and then loop through the array counting the valid elements.
If the array is guaranteed to only be accessed in sequence, you can beat the full iterative IEnumerable Count (for larger arrays) with a little divide and conquer, e.g.
static int DivideCount(int[] arr, int idx, int bottom, int top)
{
if (idx <= 0)
return 0;
else if (idx >= arr.Length - 1)
return arr.Length;
else if (arr[idx] == 0 && arr[idx - 1] != 0)
return idx;
else if (arr[idx] == 0 && arr[idx - 1] == 0)
return DivideCount(arr, bottom + ((idx - bottom) / 2), bottom, idx);
else if (arr[idx] != 0 && arr[idx - 1] != 0)
return DivideCount(arr, top - ((top - idx) / 2), idx, top);
else
return -1; // hello compiler
}
int[] intArray = new int[10];
intArray[0] = 35;
intArray[1] = 65;
intArray[2] = 98;
var count = DivideCount(intArray, intArray.Length / 2, 0, intArray.Length);
None of the previous solutions are optimal if someone other than you initialized the array (i.e. you don't have the option of initializing the array values to invalid values -- null, -1, etc.).
Suppose you have an array:
var arr = new[] {0, 10, 18, 0, 20, 0, 0, 0, 0, 0, 0, 0};
If you simply count the number of zero entries:
int result = arr.Count(i => i != 0);
Count() returns 3, when in reality 5 entries have been initialized. An example would be an array of raw bytes that were read out of an audio file into a buffer, and you want to know the index of the last element that was read.
An alternative that isn't perfect but could do what you're looking for is to look for the last non-zero entry, as described here: Linq - Get the Index of the Last Non-Zero Number of Array
I initialized an Array as
Double[][] myarr = Enumerable.Repeat(new double[12], 13).ToArray();
Then in a loop i am incrementing values like
myarr[0][0]++;
This causes all values like myarr[1][0], myarr[2][0], myarr[3][0] ..... myarr[12][0] to increment by one.
This problem is not occurring when using a for loop (0-12) i am initializing like
myarr[i] = new double[12];
Why is this so?
Other answers have explained the problem. The solution is to create a new array on each iteration, e.g.
double[][] myarr = Enumerable.Range(0, 13)
.Select(ignored => new double[12])
.ToArray();
It's because new double[12] creates a single array object in memory - Enumerable.Repeat is simply providing you with multiple references to that array.
This is expected behavior - array is a referebce type. You are creating a jagged array i.e. array of arrays. All elements of your outer array references the same inside array i.e the first argument of Repeat call, so changes in the inside array will be reflected at on indices (because all indices refer to the same array).
With new double[12] you are creating reference to array of doubles, and then you repeate the reference 12 times, so myarr[0..n] will have reference to one memory region.
You can use the folowing method to resolve thw issue
static T[][] CreateArray<T>(int rows, int cols)
{
T[][] array = new T[rows][];
for (int i = 0; i < array.GetLength(0); i++)
array[i] = new T[cols];
return array;
}
Or with custom Repeat method which calls action every step:
public static IEnumerable<TResult> RepeatAction<TResult>(Action<TResult> elementAction, int count)
{
for (int i = 0; i < count; i++)
{
yield return elementAction();
}
yield break;
}
usage
RepeatAction(()=>new double[12], 12);
Arrays are references. In the Repeat call you create one array and assign its reference 12 times. In your loop however you create 12 distinct arrays.
Repeat() basically just capture and yields the same element multiple times, so you got multiple references to the same object instance in the memory.
This is how Repeat() is implemented:
private static IEnumerable<TResult> RepeatIterator<TResult>(TResult element, int count)
{
for (int i = 0; i < count; i++)
{
yield return element;
}
yield break;
}
I have this assignment where I must delete a chosen element from an array, so I came up with this code:
strInput = Console.ReadLine();
for (int i = 0; i < intAmount; i++)
{
if (strItems[i] == strInput)
{
strItems[i] = null;
for (int x = 0; x < intAmount-i; x++)
{
i = i + 1;
strItems[i - 1] = strItems[i];
}
intAmount = intAmount - 1;
}
}
The problem is that, suppose I have an array [1,2,3,4,5,], and I want to delete 1. The output would be [2,3,4,5,5]. This also happens when I choose 2, but it does not happen when I choose any other number.
What am I doing wrong?
I'm assuming you are working with a basic array of strings:
var strItems = new string[] { "1", "2", "3", "4", "5" };
In .NET, that array is always going to be 5 elements long. In order to remove an element, you are going to have to copy the remaining elements to a new array and return it. Setting the value at a position to null does not remove it from the array.
Now, with things like LINQ this is very easy (not shown here), or you could cheat using the List<> collection and do this:
var list = new List<string>(strItems);
list.Remove("3");
strItems = list.ToArray();
But I don't think that's going to teach you anything.
The first step is to find the index of the element you wish to remove. You can use Array.IndexOf to help you out. Let's find the middle element, "3":
int removeIndex = Array.IndexOf(strItems, "3");
If the element was not found, it will return a -1, so check for that before doing anything.
if (removeIndex >= 0)
{
// continue...
}
Finally you have to copy the elements (except the one at the index we don't want) to a new array. So, altogether, you end up with something like this (commented for explanation):
string strInput = Console.ReadLine();
string[] strItems = new string[] { "1", "2", "3", "4", "5" };
int removeIndex = Array.IndexOf(strItems, strInput);
if (removeIndex >= 0)
{
// declare and define a new array one element shorter than the old array
string[] newStrItems = new string[strItems.Length - 1];
// loop from 0 to the length of the new array, with i being the position
// in the new array, and j being the position in the old array
for (int i = 0, j = 0; i < newStrItems.Length; i++, j++)
{
// if the index equals the one we want to remove, bump
// j up by one to "skip" the value in the original array
if (i == removeIndex)
{
j++;
}
// assign the good element from the original array to the
// new array at the appropriate position
newStrItems[i] = strItems[j];
}
// overwrite the old array with the new one
strItems = newStrItems;
}
And now strItems will be the new array, minus the value specified for removal.
Arrays in C# are of a fixed size - once initialized you can only modify items, but you cannot add or remove items. If you want to delete an item from a collection you have two options:
1.) Create a new array that has all members of the original array minus the one you want to remove.
2.) Use a collection type that is resizable and allows to add or remove items like List<T> (List<int> in your case). This is what you would do in the "real world" if your collection is not static.
In your specific implementation i think u miss a break; statement, you should go out from the outer loop when you finish the inner loop. The assignment to null is not useful at all.
If the list is just a list of numbers why are you using strings? use integers directly if it is the case.
Your exercise seems to ask something like this, if you need to remove only one element.
public bool MyDelete(int[] array, int value) // Easy to do for strings too.
{
bool found = false;
for (int i = 0; i < array.Length; ++i)
{
if (found)
{
array[i - 1] = array[i];
}
else if (array[i] == value)
{
found = true;
}
}
return found;
}
This function will returns true if it find the specified falue, false if not.
It will move all items as you describe in your example, but of course, it will not change the size of the array.
Arrays are fixed size.
You cannot change the size of an array, simply, the language don't allows that.
Arrays are, were and will be always fixed size!
To remove an item from an array you should do something this:
public static T[] RemoveAt<T>(T[] array, int index) // hope there are not bugs, wrote by scratch.
{
int count = array.Length - 1;
T[] result = new T[count];
if (index > 0)
Array.Copy(array, 0, result, 0, index - 1);
if (index < size)
Array.Copy(array, index + 1, result, index, size - index);
return result;
}
...
strItems = RemoveAt(strItems, index);
This function will create a new array that contains all elements except the one at the index you specify.
Now, why someone would do something like this instead of using a List or a Dictionary or wathever?
Use directly a List without using an array.
Can use Except method to filter the data
AllData = {10, 30, 20, 50}
FilterData = {30, 20}
Result = AllData.Except(​FilterData)
Result will be {10, 50}
Arrays are a fixed sized, you can't shorten their length without creating a new array. All you can do is store the length of valid elements in the array (ie. after you remove 1 the length is 4).
Also, I'm not sure if the order of elements in your array is important, but if it's not you could swap the first and last elements rather than moving every element after the one that's removed forward 1 position.
An alternative to using an array is using a collection such as an ArrayList which will take care of resizing, removing and keeping a count of the amount of items in it, plus a lot more.
However, since this is homework you might have to use arrays. Either keep track of the length with a variable, as opposed to using array.length, or create a new array each time you want to change the size. If you don't have to use arrays then look at the collections you can use in C#.