I have an array of Foo objects. How do I remove the second element of the array?
I need something similar to RemoveAt() but for a regular array.
If you don't want to use List:
var foos = new List<Foo>(array);
foos.RemoveAt(index);
return foos.ToArray();
You could try this extension method that I haven't actually tested:
public static T[] RemoveAt<T>(this T[] source, int index)
{
T[] dest = new T[source.Length - 1];
if( index > 0 )
Array.Copy(source, 0, dest, 0, index);
if( index < source.Length - 1 )
Array.Copy(source, index + 1, dest, index, source.Length - index - 1);
return dest;
}
And use it like:
Foo[] bar = GetFoos();
bar = bar.RemoveAt(2);
The nature of arrays is that their length is immutable. You can't add or delete any of the array items.
You will have to create a new array that is one element shorter and copy the old items to the new array, excluding the element you want to delete.
So it is probably better to use a List instead of an array.
I use this method for removing an element from an object array. In my situation, my arrays are small in length. So if you have large arrays you may need another solution.
private int[] RemoveIndices(int[] IndicesArray, int RemoveAt)
{
int[] newIndicesArray = new int[IndicesArray.Length - 1];
int i = 0;
int j = 0;
while (i < IndicesArray.Length)
{
if (i != RemoveAt)
{
newIndicesArray[j] = IndicesArray[i];
j++;
}
i++;
}
return newIndicesArray;
}
LINQ one-line solution:
myArray = myArray.Where((source, index) => index != 1).ToArray();
The 1 in that example is the index of the element to remove -- in this example, per the original question, the 2nd element (with 1 being the second element in C# zero-based array indexing).
A more complete example:
string[] myArray = { "a", "b", "c", "d", "e" };
int indexToRemove = 1;
myArray = myArray.Where((source, index) => index != indexToRemove).ToArray();
After running that snippet, the value of myArray will be { "a", "c", "d", "e" }.
This is a way to delete an array element, as of .Net 3.5, without copying to another array - using the same array instance with Array.Resize<T>:
public static void RemoveAt<T>(ref T[] arr, int index)
{
for (int a = index; a < arr.Length - 1; a++)
{
// moving elements downwards, to fill the gap at [index]
arr[a] = arr[a + 1];
}
// finally, let's decrement Array's size by one
Array.Resize(ref arr, arr.Length - 1);
}
Here is an old version I have that works on version 1.0 of the .NET framework and does not need generic types.
public static Array RemoveAt(Array source, int index)
{
if (source == null)
throw new ArgumentNullException("source");
if (0 > index || index >= source.Length)
throw new ArgumentOutOfRangeException("index", index, "index is outside the bounds of source array");
Array dest = Array.CreateInstance(source.GetType().GetElementType(), source.Length - 1);
Array.Copy(source, 0, dest, 0, index);
Array.Copy(source, index + 1, dest, index, source.Length - index - 1);
return dest;
}
This is used like this:
class Program
{
static void Main(string[] args)
{
string[] x = new string[20];
for (int i = 0; i < x.Length; i++)
x[i] = (i+1).ToString();
string[] y = (string[])MyArrayFunctions.RemoveAt(x, 3);
for (int i = 0; i < y.Length; i++)
Console.WriteLine(y[i]);
}
}
Not exactly the way to go about this, but if the situation is trivial and you value your time, you can try this for nullable types.
Foos[index] = null
and later check for null entries in your logic..
Try below code:
myArray = myArray.Where(s => (myArray.IndexOf(s) != indexValue)).ToArray();
or
myArray = myArray.Where(s => (s != "not_this")).ToArray();
As usual, I'm late to the party...
I'd like to add another option to the nice solutions list already present. =)
I would see this as a good opportunity for Extensions.
Reference:
http://msdn.microsoft.com/en-us/library/bb311042.aspx
So, we define some static class and in it, our Method.
After that, we can use our extended method willy-nilly. =)
using System;
namespace FunctionTesting {
// The class doesn't matter, as long as it's static
public static class SomeRandomClassWhoseNameDoesntMatter {
// Here's the actual method that extends arrays
public static T[] RemoveAt<T>( this T[] oArray, int idx ) {
T[] nArray = new T[oArray.Length - 1];
for( int i = 0; i < nArray.Length; ++i ) {
nArray[i] = ( i < idx ) ? oArray[i] : oArray[i + 1];
}
return nArray;
}
}
// Sample usage...
class Program {
static void Main( string[] args ) {
string[] myStrArray = { "Zero", "One", "Two", "Three" };
Console.WriteLine( String.Join( " ", myStrArray ) );
myStrArray = myStrArray.RemoveAt( 2 );
Console.WriteLine( String.Join( " ", myStrArray ) );
/* Output
* "Zero One Two Three"
* "Zero One Three"
*/
int[] myIntArray = { 0, 1, 2, 3 };
Console.WriteLine( String.Join( " ", myIntArray ) );
myIntArray = myIntArray.RemoveAt( 2 );
Console.WriteLine( String.Join( " ", myIntArray ) );
/* Output
* "0 1 2 3"
* "0 1 3"
*/
}
}
}
Here's how I did it...
public static ElementDefinitionImpl[] RemoveElementDefAt(
ElementDefinition[] oldList,
int removeIndex
)
{
ElementDefinitionImpl[] newElementDefList = new ElementDefinitionImpl[ oldList.Length - 1 ];
int offset = 0;
for ( int index = 0; index < oldList.Length; index++ )
{
ElementDefinitionImpl elementDef = oldList[ index ] as ElementDefinitionImpl;
if ( index == removeIndex )
{
// This is the one we want to remove, so we won't copy it. But
// every subsequent elementDef will by shifted down by one.
offset = -1;
}
else
{
newElementDefList[ index + offset ] = elementDef;
}
}
return newElementDefList;
}
In a normal array you have to shuffle down all the array entries above 2 and then resize it using the Resize method. You might be better off using an ArrayList.
private int[] removeFromArray(int[] array, int id)
{
int difference = 0, currentValue=0;
//get new Array length
for (int i=0; i<array.Length; i++)
{
if (array[i]==id)
{
difference += 1;
}
}
//create new array
int[] newArray = new int[array.Length-difference];
for (int i = 0; i < array.Length; i++ )
{
if (array[i] != id)
{
newArray[currentValue] = array[i];
currentValue += 1;
}
}
return newArray;
}
Here's a small collection of helper methods I produced based on some of the existing answers. It utilizes both extensions and static methods with reference parameters for maximum idealness:
public static class Arr
{
public static int IndexOf<TElement>(this TElement[] Source, TElement Element)
{
for (var i = 0; i < Source.Length; i++)
{
if (Source[i].Equals(Element))
return i;
}
return -1;
}
public static TElement[] Add<TElement>(ref TElement[] Source, params TElement[] Elements)
{
var OldLength = Source.Length;
Array.Resize(ref Source, OldLength + Elements.Length);
for (int j = 0, Count = Elements.Length; j < Count; j++)
Source[OldLength + j] = Elements[j];
return Source;
}
public static TElement[] New<TElement>(params TElement[] Elements)
{
return Elements ?? new TElement[0];
}
public static void Remove<TElement>(ref TElement[] Source, params TElement[] Elements)
{
foreach (var i in Elements)
RemoveAt(ref Source, Source.IndexOf(i));
}
public static void RemoveAt<TElement>(ref TElement[] Source, int Index)
{
var Result = new TElement[Source.Length - 1];
if (Index > 0)
Array.Copy(Source, 0, Result, 0, Index);
if (Index < Source.Length - 1)
Array.Copy(Source, Index + 1, Result, Index, Source.Length - Index - 1);
Source = Result;
}
}
Performance wise, it is decent, but it could probably be improved. Remove relies on IndexOf and a new array is created for each element you wish to remove by calling RemoveAt.
IndexOf is the only extension method as it does not need to return the original array. New accepts multiple elements of some type to produce a new array of said type. All other methods must accept the original array as a reference so there is no need to assign the result afterward as that happens internally already.
I would've defined a Merge method for merging two arrays; however, that can already be accomplished with Add method by passing in an actual array versus multiple, individual elements. Therefore, Add may be used in the following two ways to join two sets of elements:
Arr.Add<string>(ref myArray, "A", "B", "C");
Or
Arr.Add<string>(ref myArray, anotherArray);
I know this article is ten years old and therefore probably dead, but here's what I'd try doing:
Use the IEnumerable.Skip() method, found in System.Linq. It will skip the selected element from the array, and return another copy of the array that only contains everything except the selected object. Then just repeat that for every element you want removed and after that save it to a variable.
For example, if we have an array named "Sample" (of type int[]) with 5 numbers. We want to remove the 2nd one, so trying "Sample.Skip(2);" should return the same array except without the 2nd number.
First step
You need to convert the array into a list, you could write an extension method like this
// Convert An array of string to a list of string
public static List<string> ConnvertArrayToList(this string [] array) {
// DECLARE a list of string and add all element of the array into it
List<string> myList = new List<string>();
foreach( string s in array){
myList.Add(s);
}
return myList;
}
Second step
Write an extension method to convert back the list into an array
// convert a list of string to an array
public static string[] ConvertListToArray(this List<string> list) {
string[] array = new string[list.Capacity];
array = list.Select(i => i.ToString()).ToArray();
return array;
}
Last steps
Write your final method, but remember to remove the element at index before converting back to an array like the code show
public static string[] removeAt(string[] array, int index) {
List<string> myList = array.ConnvertArrayToList();
myList.RemoveAt(index);
return myList.ConvertListToArray();
}
examples codes could be find on my blog, keep tracking.
Related
I have an array of Foo objects. How do I remove the second element of the array?
I need something similar to RemoveAt() but for a regular array.
If you don't want to use List:
var foos = new List<Foo>(array);
foos.RemoveAt(index);
return foos.ToArray();
You could try this extension method that I haven't actually tested:
public static T[] RemoveAt<T>(this T[] source, int index)
{
T[] dest = new T[source.Length - 1];
if( index > 0 )
Array.Copy(source, 0, dest, 0, index);
if( index < source.Length - 1 )
Array.Copy(source, index + 1, dest, index, source.Length - index - 1);
return dest;
}
And use it like:
Foo[] bar = GetFoos();
bar = bar.RemoveAt(2);
The nature of arrays is that their length is immutable. You can't add or delete any of the array items.
You will have to create a new array that is one element shorter and copy the old items to the new array, excluding the element you want to delete.
So it is probably better to use a List instead of an array.
I use this method for removing an element from an object array. In my situation, my arrays are small in length. So if you have large arrays you may need another solution.
private int[] RemoveIndices(int[] IndicesArray, int RemoveAt)
{
int[] newIndicesArray = new int[IndicesArray.Length - 1];
int i = 0;
int j = 0;
while (i < IndicesArray.Length)
{
if (i != RemoveAt)
{
newIndicesArray[j] = IndicesArray[i];
j++;
}
i++;
}
return newIndicesArray;
}
LINQ one-line solution:
myArray = myArray.Where((source, index) => index != 1).ToArray();
The 1 in that example is the index of the element to remove -- in this example, per the original question, the 2nd element (with 1 being the second element in C# zero-based array indexing).
A more complete example:
string[] myArray = { "a", "b", "c", "d", "e" };
int indexToRemove = 1;
myArray = myArray.Where((source, index) => index != indexToRemove).ToArray();
After running that snippet, the value of myArray will be { "a", "c", "d", "e" }.
This is a way to delete an array element, as of .Net 3.5, without copying to another array - using the same array instance with Array.Resize<T>:
public static void RemoveAt<T>(ref T[] arr, int index)
{
for (int a = index; a < arr.Length - 1; a++)
{
// moving elements downwards, to fill the gap at [index]
arr[a] = arr[a + 1];
}
// finally, let's decrement Array's size by one
Array.Resize(ref arr, arr.Length - 1);
}
Here is an old version I have that works on version 1.0 of the .NET framework and does not need generic types.
public static Array RemoveAt(Array source, int index)
{
if (source == null)
throw new ArgumentNullException("source");
if (0 > index || index >= source.Length)
throw new ArgumentOutOfRangeException("index", index, "index is outside the bounds of source array");
Array dest = Array.CreateInstance(source.GetType().GetElementType(), source.Length - 1);
Array.Copy(source, 0, dest, 0, index);
Array.Copy(source, index + 1, dest, index, source.Length - index - 1);
return dest;
}
This is used like this:
class Program
{
static void Main(string[] args)
{
string[] x = new string[20];
for (int i = 0; i < x.Length; i++)
x[i] = (i+1).ToString();
string[] y = (string[])MyArrayFunctions.RemoveAt(x, 3);
for (int i = 0; i < y.Length; i++)
Console.WriteLine(y[i]);
}
}
Not exactly the way to go about this, but if the situation is trivial and you value your time, you can try this for nullable types.
Foos[index] = null
and later check for null entries in your logic..
Try below code:
myArray = myArray.Where(s => (myArray.IndexOf(s) != indexValue)).ToArray();
or
myArray = myArray.Where(s => (s != "not_this")).ToArray();
As usual, I'm late to the party...
I'd like to add another option to the nice solutions list already present. =)
I would see this as a good opportunity for Extensions.
Reference:
http://msdn.microsoft.com/en-us/library/bb311042.aspx
So, we define some static class and in it, our Method.
After that, we can use our extended method willy-nilly. =)
using System;
namespace FunctionTesting {
// The class doesn't matter, as long as it's static
public static class SomeRandomClassWhoseNameDoesntMatter {
// Here's the actual method that extends arrays
public static T[] RemoveAt<T>( this T[] oArray, int idx ) {
T[] nArray = new T[oArray.Length - 1];
for( int i = 0; i < nArray.Length; ++i ) {
nArray[i] = ( i < idx ) ? oArray[i] : oArray[i + 1];
}
return nArray;
}
}
// Sample usage...
class Program {
static void Main( string[] args ) {
string[] myStrArray = { "Zero", "One", "Two", "Three" };
Console.WriteLine( String.Join( " ", myStrArray ) );
myStrArray = myStrArray.RemoveAt( 2 );
Console.WriteLine( String.Join( " ", myStrArray ) );
/* Output
* "Zero One Two Three"
* "Zero One Three"
*/
int[] myIntArray = { 0, 1, 2, 3 };
Console.WriteLine( String.Join( " ", myIntArray ) );
myIntArray = myIntArray.RemoveAt( 2 );
Console.WriteLine( String.Join( " ", myIntArray ) );
/* Output
* "0 1 2 3"
* "0 1 3"
*/
}
}
}
Here's how I did it...
public static ElementDefinitionImpl[] RemoveElementDefAt(
ElementDefinition[] oldList,
int removeIndex
)
{
ElementDefinitionImpl[] newElementDefList = new ElementDefinitionImpl[ oldList.Length - 1 ];
int offset = 0;
for ( int index = 0; index < oldList.Length; index++ )
{
ElementDefinitionImpl elementDef = oldList[ index ] as ElementDefinitionImpl;
if ( index == removeIndex )
{
// This is the one we want to remove, so we won't copy it. But
// every subsequent elementDef will by shifted down by one.
offset = -1;
}
else
{
newElementDefList[ index + offset ] = elementDef;
}
}
return newElementDefList;
}
In a normal array you have to shuffle down all the array entries above 2 and then resize it using the Resize method. You might be better off using an ArrayList.
private int[] removeFromArray(int[] array, int id)
{
int difference = 0, currentValue=0;
//get new Array length
for (int i=0; i<array.Length; i++)
{
if (array[i]==id)
{
difference += 1;
}
}
//create new array
int[] newArray = new int[array.Length-difference];
for (int i = 0; i < array.Length; i++ )
{
if (array[i] != id)
{
newArray[currentValue] = array[i];
currentValue += 1;
}
}
return newArray;
}
Here's a small collection of helper methods I produced based on some of the existing answers. It utilizes both extensions and static methods with reference parameters for maximum idealness:
public static class Arr
{
public static int IndexOf<TElement>(this TElement[] Source, TElement Element)
{
for (var i = 0; i < Source.Length; i++)
{
if (Source[i].Equals(Element))
return i;
}
return -1;
}
public static TElement[] Add<TElement>(ref TElement[] Source, params TElement[] Elements)
{
var OldLength = Source.Length;
Array.Resize(ref Source, OldLength + Elements.Length);
for (int j = 0, Count = Elements.Length; j < Count; j++)
Source[OldLength + j] = Elements[j];
return Source;
}
public static TElement[] New<TElement>(params TElement[] Elements)
{
return Elements ?? new TElement[0];
}
public static void Remove<TElement>(ref TElement[] Source, params TElement[] Elements)
{
foreach (var i in Elements)
RemoveAt(ref Source, Source.IndexOf(i));
}
public static void RemoveAt<TElement>(ref TElement[] Source, int Index)
{
var Result = new TElement[Source.Length - 1];
if (Index > 0)
Array.Copy(Source, 0, Result, 0, Index);
if (Index < Source.Length - 1)
Array.Copy(Source, Index + 1, Result, Index, Source.Length - Index - 1);
Source = Result;
}
}
Performance wise, it is decent, but it could probably be improved. Remove relies on IndexOf and a new array is created for each element you wish to remove by calling RemoveAt.
IndexOf is the only extension method as it does not need to return the original array. New accepts multiple elements of some type to produce a new array of said type. All other methods must accept the original array as a reference so there is no need to assign the result afterward as that happens internally already.
I would've defined a Merge method for merging two arrays; however, that can already be accomplished with Add method by passing in an actual array versus multiple, individual elements. Therefore, Add may be used in the following two ways to join two sets of elements:
Arr.Add<string>(ref myArray, "A", "B", "C");
Or
Arr.Add<string>(ref myArray, anotherArray);
I know this article is ten years old and therefore probably dead, but here's what I'd try doing:
Use the IEnumerable.Skip() method, found in System.Linq. It will skip the selected element from the array, and return another copy of the array that only contains everything except the selected object. Then just repeat that for every element you want removed and after that save it to a variable.
For example, if we have an array named "Sample" (of type int[]) with 5 numbers. We want to remove the 2nd one, so trying "Sample.Skip(2);" should return the same array except without the 2nd number.
First step
You need to convert the array into a list, you could write an extension method like this
// Convert An array of string to a list of string
public static List<string> ConnvertArrayToList(this string [] array) {
// DECLARE a list of string and add all element of the array into it
List<string> myList = new List<string>();
foreach( string s in array){
myList.Add(s);
}
return myList;
}
Second step
Write an extension method to convert back the list into an array
// convert a list of string to an array
public static string[] ConvertListToArray(this List<string> list) {
string[] array = new string[list.Capacity];
array = list.Select(i => i.ToString()).ToArray();
return array;
}
Last steps
Write your final method, but remember to remove the element at index before converting back to an array like the code show
public static string[] removeAt(string[] array, int index) {
List<string> myList = array.ConnvertArrayToList();
myList.RemoveAt(index);
return myList.ConvertListToArray();
}
examples codes could be find on my blog, keep tracking.
Here's an example of an array
int[] N = new int[]{1,0,6,0,3,4};
for (int i = 0; i < N.Length; i++){
if (N[i] == 0){
//remove N[i] and moveback everything }
foreach (string i in N) {
Console.Write("{0} ", i + " ");
}
Example output would be
1 6 3 4
Filtering to create new array
N = N.Where(x => x != 0).ToArray();
It seems like a nice fit for a generic extension method, and Array.Copy to have a nice fast solution
Note : This recreates an array.
Given
public static class Extensions
{
public static T[] RemoveElement<T>(this T[] source, int index)
where T : new()
{
if(index >= source.Length) throw new ArgumentOutOfRangeException(nameof(index));
// create new array
var result = new T[source.Length - 1];
// Copy the first part
Array.Copy(source, 0, result, 0, index);
// Copy the second part
Array.Copy(source, index+1, result, index, source.Length - (index+1));
return result;
}
}
Usage
int[] N = new int[]{1,0,6,0,3,4};
var result = N.RemoveElement(1);
Example
public static void Main()
{
int[] N = new int[]{1,0,6,0,3,4};
Console.WriteLine(string.Join(",", N.RemoveElement(1)));
Console.WriteLine(string.Join(",", N.RemoveElement(0)));
Console.WriteLine(string.Join(",", N.RemoveElement(5)));
}
Output
1,6,0,3,4
0,6,0,3,4
1,0,6,0,3
Full Demo Here
Additional Resources
Copy(Array, Int32, Array, Int32, Int32)
Copies a range of elements from an Array starting at the specified
source index and pastes them to another Array starting at the
specified destination index. The length and the indexes are specified
as 32-bit integers.
You can use this:
int[] N = new int[]{1,0,6,0,3,4};
var foos = new List<int>(N);
int indexToRemove = 1;
foos.RemoveAt(indexToRemove);
N = foos.ToArray();
foreach(int elem in N )
Console.WriteLine(elem);
FYI: for high performance/frequent access, linq is not recommended.
I want to get the index of an array which I have done with Array.IndexOf(array, value). This works good with one value but I want to get every occurrence of the value and store the index's into another array. For example, the name 'tom' appears 5 times in an array, I want to find the index positions of each one.
Maybe something like this? This uses a list rather than an array, but it follows the same idea.
List<int> Indexes = new List<int>();
for (int i = 0; i < array.Count(); i++)
{
if (array[i] == "tom")
{
Indexes.Add(i);
}
}
This solution is like the previous one, but will run faster:
string value = "tom";
int[] indices = stringArray.Where(s => s != null)
.Select((s, i) => s.Equals(value) ? i: -1)
.Where(i => i >= 0)
.ToArray();
If I'm not mistaken, you can add another parameter to IndexOf(), which will let you specify where in the array to start. This should give you more or less what you need:
var indices = new List<int>();
int i = Array.IndexOf(array, val);
while(i > -1){
indices.Add(i);
i = Array.IndexOf(array, val, i+1);
}
// ... and if it is important to have the result as an array:
int[] result = indices.ToArray();
Practical example:
var array = new int[]{ 1, 2, 3, 3, 4, 5, 3, 6, 7, 8, 3};
int val = 3;
var indices = new List<int>();
int i = Array.IndexOf(array, val);
while(i > -1){
indices.Add(i);
i = Array.IndexOf(array, val, i+1);
}
// ... and if it is important to have the result as an array:
int[] result = indices.ToArray();
Edit: Just realized a while-loop may well be a lot cleaner than a for-loop for this.
Edit 2: Due to popular demand (see comment below), here`s the original beautiful non-basic for-loop, re-introduced just for your reading pleasure:
for(int i = Array.IndexOf(array, val); i > -1; i = Array.IndexOf(array, val, i+1)){
indices.Add(i);
}
Could create an extension method to do it
namespace Extensions
{
public static class ArrayExtension
{
public static IEnumerable<int> GetIndicesOf<T>(this T[] target, T val, int start = 0)
{
EqualityComparer<T> comparer = EqualityComparer<T>.Default;
for (int i = start; i < target.Length; i++)
{
if (comparer.Equals(target[i], val))
{
yield return i;
}
}
}
}
}
Add the using statement for your namespace with the extension method using Extensions; in the file you want to call it in.
Then to call it just do the following to get the indices.
IEnumerable<int> indices = array.GetIndicesOf(value);
or to get an array just do
int[] indicies = array.GetIndicesOf(value).ToArray();
You can use LINQ's Select overload which uses elements index as well, like:
var indices = stringArray.Select((s, i) => new {Value = s, Index = i})
.Where(r => r.Value == "tom")
.Select(r => r.Index);
If I have a simple Utility function that copies an array to a new array:
public static object[] CopyTo(object[] original, int startIndex, int endIndex)
{
List<object> copied - new List<object>();
for (int i = startIndex; i <= endIndex; i++)
{
copied.Add(original[i]);
}
return copied.ToArray();
}
and I want to then be able to call it like this:
int[] newThing = CopyTo(new int[] { 10, 9, 8, 7, 6 }, 2, 4);
the compiler errors saying cannot convert from int[] to object[]. This is expected since my CopyTo function specifically wants an object array, not an integer array.
How can I change the declaration of CopyTo in order for it to dynamically accept and return an array of any type? I believe Generics is the way (though I'm not too familiar with this) so I tried:
public static T[] CopyTo(T[] original, int startIndex......)
but the compiler won't recognise T as a type.
To make it generic use following code:
public static T[] CopyTo<T>(T[] original, int startIndex, int endIndex)
{
List<T> copied = new List<T>();
for (int i = startIndex; i <= endIndex; i++)
{
copied.Add(original[i]);
}
return copied.ToArray();
}
Edit:
Just to mention, you can also do this without creating a List<T> and returning the list as an array. Just create an array (with length equal to the count of wanted elements) and fill it up:
public static T[] CopyTo<T>(T[] original, int startIndex, int endIndex)
{
int count = (endIndex - startIndex) + 1;
int index = 0;
T[] copied = new T[count];
for (int i = startIndex; i <= endIndex; i++)
copied[index++] = original[i];
return copied;
}
And you could also create an extension method for it:
public static class Extensions
{
public static T[] CopyTo<T>(this T[] source, int start, int end)
{
int count = (end - start) + 1;
int index = 0;
T[] copied = new T[count];
for (int i = start; i <= end; i++)
copied[index++] = source[i];
return copied;
}
}
Now you can call it like:
var original = new int[] { 10, 9, 8, 7, 6 };
var newThing = original.CopyTo(0, 2);
Or for an array of strings:
var strOrig = "one.two.three.four.five.six.seven".Split('.');
var strNew = strOrig.CopyTo(2, 5);
Try this:
public static T[] CopyTo<T>(T[] original, int startIndex, int endIndex)
{
List<T> copied = new List<T>();
for (int i = startIndex; i < endIndex; i++)
{
copied.Add(original[i]);
}
return copied.ToArray();
}
You don't need to write your own function, the .NET Framework has already everything built in. You have two options:
Array.Copy(sourceArray, srcStartIndex, targetArray, tgtStartIndex, srcNumberOfElements);
sourceArray.CopyTo(targetArray, tgtStartIndex);
I will first explain them with some examples, and at the end I will put it together to a function
public static T[] CopyFromArray<T>(this T[] sourceArray, int startIndex, int endIndex)
as you requested it in your question (CopyTo is already reserved by .NET so I renamed it to CopyFromArray).
Note that sourceArray and targetArray are arrays of any type; srcStartIndex is the start index of the sourceArray to copy from, tgtStartIndex is the start index of the targetArray to copy to, and srcNumberOfElements is the number of elements you want to copy from the source array.
The target array must be big enough to copy all elements into, otherwise you will get an error.
The elements of the source array are directly copied into the target array ("in situ"), which is why there isn't any data returned from the functions (return type is void).
Look at this example:
void Main()
{
var target = new int[20];
var srcStart=1; var tgtStart=3; var srcElements=3;
Array.Copy((new int[] { 1,2,3,4,5,6,7,8,9 }), srcStart,
target, tgtStart, srcElements);
Console.WriteLine(string.Join(",", target));
}
It works correctly and returns:
0,0,0,2,3,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Note that srcStart specifies the index in the source array, from which it starts to copy, while tgtStart specifies the index in the target array where it starts to insert, and finally, srcElements specifies how many elements there are to be copied.
Note there is also a simpler version, the .CopyTo method. It works as follows:
void Main()
{
var target = new int[20]; var tgtStart = 3;
(new int[] { 1,2,3,4,5,6,7,8,9 }).CopyTo(target, tgtStart);
Console.WriteLine(string.Join(",", target));
}
And it returns:
0,0,0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0,0,0
The 2nd parameter specifies the index at which position the data shall be inserted (just like tgtStart in the previous example), this is why the first 3 elements are 0.
You can use it with other data types too, for example:
var target = new string[20];
(new string[] { "abc", "def", "ghi" }).CopyTo(target, 3);
works in the same way.
Coming to your question, you can use the information I gave you so far to put together your own generic extension method like this:
void Main()
{
int[] newThing1 = (new int[] { 10, 9, 8, 7, 6 }).CopyFromArray(2, 4);
newThing1.Dump();
string[] newThing2 = (new string[] { "A", "B", "C", "D"}).CopyFromArray(1, 3);
newThing2.Dump();
}
public static class Extensions
{
public static T[] CopyFromArray<T>(this T[] sourceArray, int startIndex, int endIndex)
{
int numberOfElements = endIndex - startIndex + 1;
var targetArray = new T[numberOfElements];
Array.Copy(sourceArray, startIndex, targetArray, 0, numberOfElements);
return targetArray;
}
}
I want to shift one element in an array to the right each time whilst leaving the original elements in their specific order in C#.
Ok so I've been asked to reword the code I can understand why so here we go:
I might have a number 48390
//the ar elements have been commented out to show that we never know what ar contains but only the that I will always want to shift; ar[4]
int[] ar = new int[5];
//ar[0] = 4
//ar[1] = 8
//ar[2] = 3
//ar[3] = 9
//ar[4] = 0
while(ar != 04839)
{
Shift code
}
I might input 5 numbers 48390 if you notice its the same number but one digit is out. I want a while loop to rotate that 4 ar[1] to shift until the number forms 04839
I hope this makes sense. I am posting this question because most pages posting information about shifting based on shifting all elements to the right and I only really want to shift one specific element.
Thanks for looking.
edit: I should have been more specific. What if you don't know what each of the array elements could be? So I couldn't depend on "0" as an anchor. as another set of numbers might include another number for example "00238."
This method will give you a sequence of arrays made by inserting a single element into (between) each position in a given array:
public static IEnumerable<T[]> InsertElementBetweenAllPositions<T>(
T[] array, T element)
{
int newLength = array.Length + 1;
for (int i = 0; i < newLength; i++)
{
T[] rtn = new T[newLength];
rtn[i] = element;
Array.Copy(array, 0, rtn, 0, i);
Array.Copy(array, i, rtn, i + 1, array.Length - i);
yield return rtn;
}
}
For your example, you might call it as
foreach (int[] arr in InsertElementBetweenAllPositions(new[] { 6, 7, 8, 9 }, 0))
{
foreach (int i in arr)
Console.Write(i + " ");
Console.WriteLine();
}
How about this:
List<int> l = new List<int>(){0,6,7,8,9};
for (int i=1;i<5;i++)
{
l.Remove(0);
l.Insert(i, 0);
}
What's in your example is a swap, which can be implemented like:
private void Swap(ref int[] array, int index1, int index2)
{
int temp = array[index1];
array[index1] = array[index2];
array[index2] = temp;
}
Calling Swap(ref source, 0, 1) would exchange the first and second element. What you want then is:
for (int i = 0; i < a.Length-1; i++)
{
Swap(ref a, i, i+1);
}
This "bubbles" the first element up to the last position in each iteration.
From the example you need to shift elements around, and the example is a bit confusing over whether you need to loop them around to the start again. I have provided the below example that will loop around to the start - If you do not need to do that, the you can rework the if the statement.
private int[] Shift(int[] a)
{
int zeroPos = Array.IndexOf(a, 0);
int[] rtn = new int[a.Length];
a.CopyTo(rtn, 0);
if (zeroPos + 1 == a.Length)
{
rtn[0] = 0;
for (int i = 0; i < a.Length - 1; i++)
{
rtn[i + 1] = a[i];
}
}
else
{
rtn[zeroPos] = rtn[zeroPos + 1];
rtn[zeroPos + 1] = 0;
}
return rtn;
}
r=ar[0];
for (int i = 0; ar.lenght;i++)
{
ar[i]=ar[i + 1];
}
ar[ar.lenght] = r;
Have you thought about using a LinkedList instead? A linked list data structure is probably more suited to what you are trying to do than an array. The AddFirst, AddLast, AddAfter and AddBefore methods allow you to insert elements into the list in a much more efficient way than re-organizing your array each time.
The disadvantage of linked lists is that you need to read the elements in order. So, it's very efficient for inserting/deleting elements but inefficient for accessing elements randomly.
There is a good overview of LinkedLists here.
Perhaps
int oldLast = ar[ar.Length - 1];
for (int i = ar.Length - 1; i >= 0; i--)
ar[i] = i == 0 ? oldLast : ar[i - 1];
Demo
It is just a permutation of an item , below is the full source code of permutation algorithm.
static List<string> Put(char s1, string list)
{
List<string> str =new List<string>();
for (int i = 0; i < list.Length+1; i++)
{
string s = list.Substring(0, i) + s1.ToString() + list.Substring(i);
str.Add(s);
}
return str;
}
static List<string> Permute(string list,int x)
{
List<string> Result = new List<string>();
if (list.Length == 1)
{
Result.Add(list[0].ToString());
return Result;
}
else
{
char first = list[0];
list = list.Substring(x+1);
List<string> part = Permute(list,0);
foreach (string str in part)
{
List<string> hasBeenPlaced = Put(first, str);
foreach (string str2 in hasBeenPlaced)
{
Result.Add(str2);
}
}
}
return Result;
}
static void Main(string[] args)
{
List<string> per = Permute("abc",0);
for (int i = 0; i < per.Count; i++)
{
Console.WriteLine(per[i]);
}
Console.ReadKey();
}
Now if I add a break after the foreach , your problem has been solved . (it will writes all permuation for just an item which you want , not all of them....)
So change that to :
foreach (string str in part)
{
List<string> hasBeenPlaced = Put(first, str);
foreach (string str2 in hasBeenPlaced)
{
Result.Add(str2);
}
break;
}
Hope to helps you
If you you linq, that's simple :-) But you need a size larger than the array.
ShiftLeft(ar, 1);
private static int[] ShiftLeft(int[] value, int countOfShift = 1)
{
var length = value.Length;
if (countOfShift > length)
{
throw new InvalidOperationException("countOfShift must less then value's length.");
}
var tempList = new List<int>(value);
tempList.RemoveRange(length - countOfShift, countOfShift);
tempList.InsertRange(0, value.Skip(length - countOfShift));
return tempList.ToArray();
}