Given a read only collection of ints, how do I convert it to a byte array?
ReadOnlyCollection<int> collection = new List<int> { 118,48,46,56,46,50 }.AsReadOnly(); //v0.8.2
What will an elegant way to convert 'collection' to byte[] ?
You can use LINQ's Select method to cast each element from int to byte.
This will give you an IEnumerable<byte>. You can then use the ToArray() extension method to convert this to a byte[].
collection.Select(i => (byte)i).ToArray();
If you don't want to use LINQ then you can instantiate the array and use a for loop to iterate over the collection instead, assigning each value in the array.
var byteArray = new byte[collection.Count];
for (var i = 0; i < collection.Count; i++)
{
byteArray[i] = (byte)collection[i];
}
Related
I have a typed array MyType[] types;
and i want to make and independant copy of this array. i tried this
MyType[] types2 = new MyType[types.Length] ;
types2 = types ;
but this create a reference to the first. I then tried
Array.Copy( types , types2 , types.Length ) ;
but I have the same problem: changing a value in the first array changes the value in the copy as well.
How can I make a completely independent or deep copy of an Array, IList or IEnumerable?
Based on the first post, all he needs is this for "an independent copy of the array". Changes to the shallowCopy array itself would not appear in the types array (meaning element assignment, which really is what he showed above despite saying "deep copy"). If this suits your needs, it will have the best performance.
MyType[] shallowCopy = (MyType[])types.Clone();
He also mentions a "deep copy" which would be different for mutable types that are not recursive value-type aggregates of primitives. If the MyType implements ICloneable, this works great for a deep copy:
MyType[] deepCopy = (MyType[])Array.ConvertAll(element => (MyType)element.Clone());
For the impatient:
newarray = new List<T>(oldarray).ToArray();
Implement a clone method on MyType, using protected method MemberwiseClone (performs shallow copy) or using a deep cloning technique. You can have it implement an ICloneable then write several extensions methods that will clone the corresponsing collection.
interface ICloneable<T>
{
T Clone();
}
public static class Extensions
{
public static T[] Clone<T>(this T[] array) where T : ICloneable<T>
{
var newArray = new T[array.Length];
for (var i = 0; i < array.Length; i++)
newArray[i] = array[i].Clone();
return newArray;
}
public static IEnumerable<T> Clone<T>(this IEnumerable<T> items) where T : ICloneable<T>
{
foreach (var item in items)
yield return item.Clone();
}
}
You must do this because while a new array is created when you use Array.Copy it copies the references, not the objects referenced. Each type is responsible for copying itself.
If your type is serializable you can use serialization techniques to get a copy of your array (including deep copies of the items):
private static object GetCopy(object input)
{
using (MemoryStream stream = new MemoryStream())
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, input);
stream.Position = 0;
return formatter.Deserialize(stream);
}
}
To use it:
MyType[] items = new MyType[2];
// populate the items in the array
MyType[] copies = (MyType[])GetCopy(items);
I wanted to do the same thing: make a copy of an array by value for things like sorting so that I could later reinitialize another temp array with the original source array. After researching this, I found this cannot be done so simply. So, I made a workaround. I will use my own code below:
string[] planetNames = new string[] { "earth", "venus", "mars" };
string[] tempNames = new string[planetNames.Length];
for (int i = 0; i < planetNames.Length; i++)
{
tempNames[i] = planetNames[i];
}
planetNames is my source array. tempNames is the array which I will later sort independently of planetNames. I have tested this and this code does not sort planetNames when I sort tempNames which is what I was attempting to achieve.
If you want to create a copy of just an array with references to objects in old array (or if you have array of value type objects), simplest solution is
var newArray = oldArray.ToArray()
If you want deep copy you should have a method which copies single object of your type (e.g. public MyType Copy(MyType obj)). Then solution will look like
var newArray = oldArray.Select(x => Copy(x)).ToArray()
I've found if you just want a simple char array copy you can trick C# into doing a copy by value using the char:
char[] newchararray = new char[desiredchararray.Length];
for (int k = 0; k < desiredchararray.Length; k++)
{
char thecharacter = newchararray[k];
newchararray[k] = thecharacter;
oldchararray[k] = oldchararray[k] + 1;
}
Seems to work for me but if anyone disagrees please let me know :)
Copying the value of the array in this case are numbers
int[] arr = { 1, 2, 3, 4, 5 };
int[] copyArr = new int[arr.Length];
for (int i = 0; i <arr.Length; i++)
{
copyArr[i]=arr[arr.Length-i-1];
}
Console.WriteLine(string.Join(" ",arr));**
I has a multidimentional string array as below
string[][] data = new string[3][];
the item in the string array as below
data[0]
[0] "EUG5" string
[1] "FA1" string
data[1]
[0] "9.000000" string
[1] "1000" string
data[2]
[0] "1" string
[1] "0" string
I wish to remove the data[0][1], data[1][1] and data[2][1], this is base on the condition on data[2] where it is "0". Is it possible to do this?
You can use Array.Resize to do what you want to do. Try this LINQpad script:
var data = new string[][]{new []{"EUG5","FA1"},new []{"9.000000","1000"},new []{"1","0"}};
data.Dump();
Array.Resize(ref data[0],1);
Array.Resize(ref data[1],1);
Array.Resize(ref data[2],1);
data.Dump();
It produces this:
You can also use Array.Copy to move elements around, so this is the more generic case:
var data = new string[][]{new []{"EUG5","FA1"},new []{"9.000000","1000"},new []{"1","0"}};
data.Dump();
var colToDelete = 0;
for (int i = 0; i < data.Length; i++)
{
Array.Copy(data[i],colToDelete+1,data[i],colToDelete,data[i].Length-colToDelete-1);
Array.Resize(ref data[i],data[i].Length-1);
}
data.Dump();
but like the other posters correctly state, it's way easier with a List.
You cannot remove elements from an Array object in C#, all Arrays are immutable. To get the flexibility you are looking for you want to use the List object.
If for some reason you are stuck and have to use arrays, then you could make a method that accepts an Array and Returns an Array. Then you could remove the objects like this:
public string[][] RemoveElement(string[][] array, int coordinateA, int coordinateB)
{
var ListOfItems = new List<List<string>>();
foreach(string[] item in array)
ListOfItems.add(new List<string>(item));
ListOfItems[coordinateA].RemoveAt(coordinateB);
var ReturnArray = new string[ListOfItems.Length][]();
for(int i = 0; i < ListOfItems.Length; i++)
ReturnArray[i] = ListOfItems[i].ToArray();
return ReturnArray;
}
Of couse this is not a very optimized solution, but it will get the job done. There probably are extension method solutions for removing elements from arrays, but it would be far better to just use List object, and then return an array at the end of your code by calling List.ToArray() if it is necessary.
If you don't mind in creating new Array of Arrays instead of reusing existing array you could do this.
data = data
.Select(x=> data[2][1] == "0"? // Condition to filter
x.Take(1).ToArray()
: x.ToArray())
.ToArray();
Check this Demo
I have declared my int[] as follows
int[] iroleID = new int[] { };
My code for getting the values from database and assigning to iroleid is as follows
if (oAuthenticate.getTaskID(out m_oDataSet1, "uspgetTaskID"))
{
for (int iTaskid = 0; iTaskid < m_oDataSet1.Tables[0].Rows.Count; iTaskid++)
{
iroleID = Convert.ToInt32(m_oDataSet1.Tables[0].Rows[iTaskid]["RoleID"].ToString());
strTaskID = m_oDataSet1.Tables[0].Rows[iTaskid]["TaskID"].ToString();
arrTaskID.Add(strTaskID);
}
}
But i am getting an error as mentioned Cannot implicitly convert type 'int' to 'int[]' can any one help me
And no surprise here. Look at
iroleID = Convert.ToInt32(...);
Convert.ToIn32 results in an int just like the compiler claims.
Either do something like:
if (oAuthenticate.getTaskID(out m_oDataSet1, "uspgetTaskID"))
{
var iroleID = new int[m_oDataSet1.Tables[0].Rows.Count];
for (int iTaskid = 0; iTaskid < m_oDataSet1.Tables[0].Rows.Count; iTaskid++)
{
iroleID[iTaskid] = Convert.ToInt32(m_oDataSet1.Tables[0].Rows[iTaskid]["RoleID"].ToString());
/* ... */
}
}
or rethink your algorithm.
PS: I can hardly tell you what exactly to do as you don't show what the purpose of iRoleID is.
off course!
iroleID = Convert.ToInt32(m_oDataSet1.Tables[0].Rows[iTaskid]["RoleID"].ToString());
iroleID is an int array; Convert.ToInt32() returns an int .
so:
-you must declare an int variable tu store Convert.ToInt32() value
or
-just add Convert.ToInt32() result to iroleID ( iroleID.Add(Convert.ToInt32(...)) )
Sure, you can't just assign the int value to the int[] variable. Probably you need to add items to the collection. Change your int[] iroleID = new int[] { }; to List<int> iroleID = new List<int>(); and then change code to:
if (oAuthenticate.getTaskID(out m_oDataSet1, "uspgetTaskID"))
{
for (int iTaskid = 0; iTaskid < m_oDataSet1.Tables[0].Rows.Count; iTaskid++)
{
iroleID.Add(Convert.ToInt32(m_oDataSet1.Tables[0].Rows[iTaskid]["RoleID"].ToString()));
strTaskID = m_oDataSet1.Tables[0].Rows[iTaskid]["TaskID"].ToString();
arrTaskID.Add(strTaskID);
}
}
iroleID = Convert.ToInt32(m_oDataSet1.Tables[0].Rows[iTaskid]["RoleID"].ToString());
This would convert the RoleID columns value to an integer. You are taking this integer and trying to assign it to an integer array which of course is not possible. What exactly is your idea? If it is to populate a single array with all the IDs you can do the same as you did but assign it to a normal integer and then add that integer to a list or something.
You can also just use plain ADO.NET to retrieve all the values from that column and cast it to an List. That would be better.
One problem has already been answered, you must add it to an array giving the position you want
iroleID[iTaskid] = Convert.ToInt32(m_oDataSet1.Tables[0].Rows[iTaskid]["RoleID"].ToString());
the other problem is, that you create an array. You must give the length of the array.
int[] iroleID = new int[m_oDataSet1.Tables[0].Rows.Count];
Use indexing for the int array to assign a value, you can't assign an integer directly to an integer array.
iroleID[0] = Convert.ToInt32(m_oDataSet1.Tables[0].Rows[iTaskid]["RoleID"].ToString());
I have an arraylist of doubles returned by a JSON library. After the JSON parser's decode method is run, we have this in the C# locals window:
Name Value Type
myObj Count=4 object {System.Collections.ArrayList}
[0] 100.0 object {double}
[1] 244.0 object {double}
[2] 123.0 object {double}
[3] 999.0 object {double}
My goal is to produce an array of integers from this ArrayList. It would be simple to iterate and do this one value at a time, but I'd like to know how to do it using the built-in converter functionality. I have been reading theads on ConvertAll but I cannot get it to work.
I do not have control of the JSON library so I must begin with the ArrayList.
Thanks
Linq:
var array = (from double d in list
select (int)d).ToArray();
You need to be careful with ArrayLists because of boxing. Thus:
// list is ArrayList
int[] array = Array.ConvertAll(list.ToArray(), o => (int)(double)o);
Note the cast is framed as (int)(double). This first unboxes the boxed double and then casts to an int.
To do this in older versions of .NET
// list is ArrayList
int[] array = Array.ConvertAll(
list.ToArray(),
delegate(object o) { return (int)(double)o; }
);
An alternative is
// list is ArrayList
int[] array = Array.ConvertAll(
(double[])list.ToArray(typeof(double)),
o => (int)o
);
Here we do not need an unboxing operation because we have first converted the ArrayList to an array of unboxed doubles.
To do this in older versions of .NET
// list is ArrayList
int[] array = Array.ConvertAll(
(double[])list.ToArray(typeof(double)),
delegate(double o) { return (int)o; }
);
I would think something like this (with converter):
private void Main()
{
List<Double> lstd = new List<Double>();
lstd.Add(100.0);
lstd.Add(244.0);
lstd.Add(123.0);
lstd.Add(999.0);
List<int> lsti = lstd.ConvertAll(new Converter<double, int>(DoubleToInt));
}
public static int DoubleToInt(double dbl)
{
return (int)dbl;
}
If you want a sample of a working solution using ConvertAll, here's a quick snippet.
public static void testCOnvertAll()
{
List<double> target = new List<double>();
target.Add(2.3);
target.Add(2.4);
target.Add(3.2);
List<int> result = target.ConvertAll<int>(new Converter<double, int>(DoubleToInt));
}
public static int DoubleToInt(double toConvert)
{
return Convert.ToInt32(toConvert);
}
The linq options are cleaner, but if you don't have linq.
//Assuming someValues is your input array and you're sure you don't need to check the types
int[] outputValues = new int[someValues.Count];
for (int i = 0; i < someValues.Count; i++)
outputValues[i] = (int)someValues[i];
I have a typed array MyType[] types;
and i want to make and independant copy of this array. i tried this
MyType[] types2 = new MyType[types.Length] ;
types2 = types ;
but this create a reference to the first. I then tried
Array.Copy( types , types2 , types.Length ) ;
but I have the same problem: changing a value in the first array changes the value in the copy as well.
How can I make a completely independent or deep copy of an Array, IList or IEnumerable?
Based on the first post, all he needs is this for "an independent copy of the array". Changes to the shallowCopy array itself would not appear in the types array (meaning element assignment, which really is what he showed above despite saying "deep copy"). If this suits your needs, it will have the best performance.
MyType[] shallowCopy = (MyType[])types.Clone();
He also mentions a "deep copy" which would be different for mutable types that are not recursive value-type aggregates of primitives. If the MyType implements ICloneable, this works great for a deep copy:
MyType[] deepCopy = (MyType[])Array.ConvertAll(element => (MyType)element.Clone());
For the impatient:
newarray = new List<T>(oldarray).ToArray();
Implement a clone method on MyType, using protected method MemberwiseClone (performs shallow copy) or using a deep cloning technique. You can have it implement an ICloneable then write several extensions methods that will clone the corresponsing collection.
interface ICloneable<T>
{
T Clone();
}
public static class Extensions
{
public static T[] Clone<T>(this T[] array) where T : ICloneable<T>
{
var newArray = new T[array.Length];
for (var i = 0; i < array.Length; i++)
newArray[i] = array[i].Clone();
return newArray;
}
public static IEnumerable<T> Clone<T>(this IEnumerable<T> items) where T : ICloneable<T>
{
foreach (var item in items)
yield return item.Clone();
}
}
You must do this because while a new array is created when you use Array.Copy it copies the references, not the objects referenced. Each type is responsible for copying itself.
If your type is serializable you can use serialization techniques to get a copy of your array (including deep copies of the items):
private static object GetCopy(object input)
{
using (MemoryStream stream = new MemoryStream())
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, input);
stream.Position = 0;
return formatter.Deserialize(stream);
}
}
To use it:
MyType[] items = new MyType[2];
// populate the items in the array
MyType[] copies = (MyType[])GetCopy(items);
I wanted to do the same thing: make a copy of an array by value for things like sorting so that I could later reinitialize another temp array with the original source array. After researching this, I found this cannot be done so simply. So, I made a workaround. I will use my own code below:
string[] planetNames = new string[] { "earth", "venus", "mars" };
string[] tempNames = new string[planetNames.Length];
for (int i = 0; i < planetNames.Length; i++)
{
tempNames[i] = planetNames[i];
}
planetNames is my source array. tempNames is the array which I will later sort independently of planetNames. I have tested this and this code does not sort planetNames when I sort tempNames which is what I was attempting to achieve.
If you want to create a copy of just an array with references to objects in old array (or if you have array of value type objects), simplest solution is
var newArray = oldArray.ToArray()
If you want deep copy you should have a method which copies single object of your type (e.g. public MyType Copy(MyType obj)). Then solution will look like
var newArray = oldArray.Select(x => Copy(x)).ToArray()
I've found if you just want a simple char array copy you can trick C# into doing a copy by value using the char:
char[] newchararray = new char[desiredchararray.Length];
for (int k = 0; k < desiredchararray.Length; k++)
{
char thecharacter = newchararray[k];
newchararray[k] = thecharacter;
oldchararray[k] = oldchararray[k] + 1;
}
Seems to work for me but if anyone disagrees please let me know :)
Copying the value of the array in this case are numbers
int[] arr = { 1, 2, 3, 4, 5 };
int[] copyArr = new int[arr.Length];
for (int i = 0; i <arr.Length; i++)
{
copyArr[i]=arr[arr.Length-i-1];
}
Console.WriteLine(string.Join(" ",arr));**