data[,] into list<string> or list<object> in c# - c#

I have a array of two dimensions object[,] data;. I want to convert the first column of my object into a list<string> or a list<object>. here you have my code :
List<string> resultsFields = new List<string>();
object tmp = oRtx.get_ListFields(this.Instrument.ElementAt(i).Key.ToString(), RT_FieldRowView.RT_FRV_EXISTING, RT_FieldColumnView.RT_FCV_VALUE);
if (tmp != null)
{
object[,] data = (object[,])Convert.ChangeType(tmp, typeof(object[,]));
for (int j = 0; j < numItems; j++)
resultsFields.Add(data[j, 0].ToString());
}
in this code, I add each items on data[j, 0] into my list.
I would like to know if there is a faster method to convert the first column of my object ([0]) into a list

The only performance improvement i can see is creating the List<> with the specified capacity:
List<string> resultsFields = new List<string>(data.GetLength(0));

Related

Split a string message into 2d array

I have a message coming containing 48 different values seperated as:
String values = "4774,55567,44477|14555,4447,5687|416644,4447,5623|...";
I need to convert it into 16 by 3 array as:
String[,] vals = {{"4774,55567,44477"},{14555,4447,5687},{416644,4447,5623}...}
I tried using the split() function but cannot figure how to feed it into the matrix
You can split it two times:
var values = "4774,55567,44477|14555,4447,5687|416644,4447,5623";
var rows = values.Split('|');
var matrix = new string[rows.Length][];
for (var i = 0; i < rows.Length; i++)
{
matrix[i] = rows[i].Split(',');
}
and a more elegant solution using LINQ:
var values = "4774,55567,44477|14555,4447,5687|416644,4447,5623";
var data = values
.Split('|')
.Select(r => r.Split(','))
.ToArray();
EDIT: as #RandRandom pointed out, the solution above creates a jagged array. The difference is explained here: link. If the jagged array is not an option for you, to create a 2d array you need to create a matrix, specifying the dimensions [rows.Length, rows[0].Split(',').Length] and with the help of 2 for-loops assign the values:
string values = "4774,55567,44477|14555,4447,5687|416644,4447,5623";
string[] rows = values.Split('|');
string[,] matrix = new string[rows.Length, rows[0].Split(',').Length];
for (int i = 0; i < rows.Length; i++)
{
string[] rowColumns = rows[i].Split(',');
for (int j = 0; j < rowColumns.Length; j++)
{
matrix[i, j] = rowColumns[j];
}
}
You can split the string based on the | character. Then, using linq.Select(), split each line based on , and create a two-dimensional array
string[] temp = values.Split('|');
var res=temp.Select(x => x.Split(',')).ToArray();
Use Linq if you can consider the jagged array instead of 2D array:
var values = "4774,55567,44477|14555,4447,5687|416644,4447,5623";
var result = values
.Split('|')
.Select(x => x.Split(','))
.ToArray();
You can use the String.Split() method to split the string into an array of substrings, and then use a nested loop to iterate through the array and add the values to the 2D array.
Here is an example :
string values = "4774,55567,44477|14555,4447,5687|416644,4447,5623|...";
string[] substrings = values.Split('|');
string[,] vals = new string[substrings.Length,3];
for (int i = 0; i < substrings.Length; i++)
{
string[] subvalues = substrings[i].Split(',');
for (int j = 0; j < subvalues.Length; j++)
{
vals[i, j] = subvalues[j];
}
}
This will split the string values by the separator '|' and create an array of substrings. Then, it will iterate through each substring and split it again by ',' and store the result in a 2D array vals with 16 rows and 3 columns.
Try following :
string values = "4774,55567,44477|14555,4447,5687|416644,4447,5623";
String[][] vals = values.Split(new char[] { '|' }).Select(x => x.Split(new char[] { ',' }).ToArray()).ToArray();
string[,] vals2 = new string[vals.GetLength(0), vals[0].Length];
for(int i = 0; i < vals.GetLength(0); i++)
{
for(int j = 0; j < vals.Length; j++)
{
vals2[i, j] = vals[i][j];
}
}

How do I convert a DataTable to a jagged array in C#?

I'm new to C# and I can't find an example of this anywhere (although I have seen similar examples but the casting was ToString, whereas in my case I want arrays of integers). I have a DataTable object,
DataTable results = dbCon.ExecuteQuery("my query");
int m = results.Rows.Count;
int n = results.Columns.Count;
I want a jagged array consisting of n one-dimensional arrays (each array being a column of the DataTable (results, in this case).
int[][] jagged = new int[n][];
for (int i = 0; i < n; i++)
{
jagged[i] = new int[m];
//var coli = results.Columns.Cast<Array>().Select(column => Convert.ToInt32(column)).ToArray();
//jagged[i] = coli;
}
I've tried a few things (for example what I commented out) but I'm quite stuck now.
If anyone knows how to do this, please post something! Thanks!
Also, to be more specific, I'd really like to use a function like the one NumPy provides to Python... dataSet = np.array(dataList).astype('float'). Double for loops are not in my best interest as my DataTable is large.
I think you also need to make the array of type object. The DataTable DataRow holds things of type object, therefore that is what you need to store them as in your jagged array.
I think this will work:
DataTable table = dbCon.ExecuteQuery("my query");
int rowCount = table.Rows.Count;
int colCount = table.Columns.Count;
object[][] objs = new object[colCount][];
for (int currentColumn = 0; currentColumn < colCount; currentColumn++)
{
objs[currentColumn] = new object[rowCount];
for (int currentRow = 0; currentRow < rowCount; currentRow++)
{
objs[currentColumn][currentRow] = table.Rows[currentRow][currentColumn];
}
}
I think, you already have this. Try:
results.Rows[rowIndex][columnIndex]
To get it into jagged array, you may go for simple for loop:
for (int i = 0; i < results.Rows.Count; i++)
{
for (int j = 0; j < results.Columns.Count; j++)
{
jagged[i][j] = results.Rows[i][j];
}
}
You can get what you want just using LINQ against the DataTable. For each column in the DataTable, you need to iterate over the rows and select that column. You need to call Cast() to Select() on the columns and AsEnumerable() to be able to Select() on the rows:
int[][] jagged = results.Columns.Cast<DataColumn>()
.Select(
col => results.AsEnumerable()
.Select(row => row.Field<int>(col))
.ToArray()
).ToArray();

A new array out of some values from existing array

If I got an array like:
string[] test = new string[5] { "hello", "world", "test", "world", "world"};
How can I make a new array out of the ones that is the same string, "world" that is where you on before hand know how many there are, here 3?
I was thinking of something like:
string[] newArray = new string[3];
for (int i = 0; i < 5; i++)
{
if (test[i].Contains("world"))
{
newArray[i] = test[i];
}
}
The problem is here: newArray[i] = test[i];
Since it's iterating from 0 to 4, there's gonna be an error since newArray is limited to 3.
How do solve this?
EDIT: I need it to be that from test (the old array) position 1, 3 and 4 should be stored at 0, 1 and 2 in the newArray.
You want to use Linq:
var newArray = test.Where(x => x.Contains("world")).ToArray();
Use a List<string> instead:
List<string> newList = new List<string>();
for (int i = 0; i < 5; i++)
{
if (test[i].Contains("world"))
{
newList.Add(test[i]);
}
}
If you really need it as an array later.. convert the list:
string[] newArray = newList.ToArray();
You are using the same index i for both test and newArray. I would suggest you create another counter variable and increment it:
string[] newArray = new string[3];
int counter = 0;
for (int i = 0; i < 5; i++)
{
if (test[i].Contains("world"))
{
newArray[counter] = test[i];
counter++;
}
}
This isn't technically your question but if you wish to make a load of arrays based of those with the same word you could do
test.GroupBy(x => x).ToList();
this will give you a List of Lists.. with your test data this will be
list1 - hello
list2 - world world world
list3 - test
Example use
var lists = test.GroupBy(x => x).ToList();
foreach(var list in lists)
{
foreach(var str in list)
{
Console.WriteLine(str);
}
Console.WriteLine();
}
With an extra helper index variable
string[] newArray = new string[3];
for (int i = 0, j = 0; i < 5; i++)
{
if (test[i].Contains("world"))
{
newArray[j++] = test[i];
if (j >= newArray.Length)
break;
}
}

Object Reference not set to instance of object

string[][] myArray = new[size][];
for(int i=0;i<2;i++){
myArray[i][0] = newValue.toString();
}
While assigning the values i get an error
I get the Object Reference not set to instance of object exception. Please help
You have created a jagged array of strings. The outermost array has been initialized to size elements, but that means there are size spaces each for a string[], each of which is currently null. You need to create the inner arrays, or create a rectangular array.
Based on the poor code, it should be something like this:
string[][] myArray = new string[size][];
for (int j = 0; j < myArray.Length; j++) {
myArray[j] = new string[3];
for (int i = 0; i < myArray[j].Length; i++) {
myArray[j][i] = newValue.ToString();
}
}
Try this
int dim1 = 2;
int dim2 = 1;
string[,] iii = new string[dim1, dim2];
for (int i = 0; i < iii.GetLength(0); i++)
{
iii[i, 0] = "myValue";
}

Initializing two dimensional array of objects

I have a 2-dimensional array of objects, which I initialize using the traditional loop:
PairDS[,] tempPb1 = new PairDS[LoopCounterMaxValue+1, LoopCounterMaxValue+1];
for (int i = 0; i <= LoopCounterMaxValue; i++)
for (int j = 0; j <= LoopCounterMaxValue; j++)
tempPb1[i, j] = new PairDS();
Is there any better way to do this using Enumerable or something?
I thought Initialize could do it, but it only works with value types.
int N = 10;
PairDS[,] temp = new PairDS[N + 1, N + 1];
temp.Initialize();
What I recommend you do is use a jagged array.
class PairDS { public PairDS(int row, int col) { } }
static void Main(string[] args)
{
int N = 10;
PairDS[][] temp = Enumerable.Range(0, N + 1).Select(
(row) => Enumerable.Range(0, N + 1).Select(
(col) => new PairDS(row, col)).ToArray()).ToArray();
}
I don't believe you can represent a multi-dimensional array as an Enumerable or List, directly because it (the CLR) has no way of knowing how you intend to index the array.
If you did work it out row by row, it'd actually be worse (ie slower) then simply looping through the array as you're doing and initializing each cell.
There's no way to directly initialize a 2D array with the Enumerable types and as some users have pointed out there's nothing directly wrong with what you're doing. If you're just looking to simplify the loop though this might be what you're looking for;
const int length = LoopCounterMaxValue + 1;
PairDS[,] tempPb1 = new PairDS[length, lenth];
for (var i = 0; i < length * length; i++) {
var column = i % length;
var row = (i - column) / length;
tempPb1[row, column] = new PairDS();
}

Categories

Resources