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];
}
}
Related
This question already has answers here:
Converting jagged array to 2D array C#
(4 answers)
Closed 3 years ago.
I am converting a list within a list to an int[][] using:
int[][] preConvertInts = processedList.Select(array => array.ToArray().ToArray()) as int[][];
I am returning an int[,] in my method. What is the best way to convert an int[][] to an int[,]?
Edit: method
public static int[,] GetIntArrayInts(string dataString){
string data = dataString;
data = data.Replace(Environment.NewLine, "\n");
List<List<int>> processedList = new List<List<int>>();
string[] rows = data.Split('\n');
foreach (string row in rows){
string[] columns = row.Split(',');
List<int> ints = new List<int>();
foreach (string column in columns){
if (int.TryParse(column, out int tileGid)) ints.Add(tileGid);
}
processedList.Add(ints);
}
int[][] preConvertInts = processedList.Select(array => array.ToArray().ToArray()) as int[][];
int[,] processedIntArray = new int[preConvertInts[0].Length, preConvertInts[1].Length];
for (int i = 0; i < preConvertInts.Length; i++){
int[] intArray = preConvertInts[i];
for (int j = 0; j < intArray.Length; j++){
processedIntArray[i, j] = preConvertInts[i][j];
}
}
return processedIntArray;
}
What is the best way to convert an int[][] to an int[,]?
it is the one that is described in this post. Yours will actually also work if all sub-arrays have the same Length. But to cite you:
Unfortunately, my array is not rectangular. – Luna
Then it would not make much sense to try to convert it. Unless you loose values or you add values to make the dimensions of all sub arrays equal.
But your problem in the code is not this conversion but this one:
I am converting a list within a list to an int[][] using:
int[][] preConvertInts = processedList.Select(array => array.ToArray().ToArray()) as int[][];
This is wrong. You will get null for preConvertInts! if you check the return value of the Select call:
You can see that it returns IEnumerable<int[]> and not int[][]. Casting it with as int[][]; does not work and masks only the fact that the 2 types are different from the compiler. What you do there is to convert each sublist into an array and then convert (the already converted array) simply again into an array.
You need to make the select in the proper way:
int [][] preConvertInts = processedList.Select(x=>x.ToArray()).ToArray();
Explanation:
1) in the first step you collect all sublists and convert each one into an array: Select(x=>x.ToArray())
2) now this call returns an IEnumerable<int[]> which you need to convert again to an array:
Select(x=>x.ToArray()).ToArray();
^^
||
note the dot behind the closing parentesis of the Select call
Jagged Array
public static T[,] ToMultiArray<T>(this IList<T[]> arrays)
{
var length = arrays[0].Length;
var result = new T[arrays.Count, length];
for (var i = 0; i < arrays.Count; i++)
{
var array = arrays[i];
if (array.Length != length)
{
throw new ArgumentException("Misaligned arrays");
}
for (var j = 0; j < length; j++)
{
result[i, j] = array[j];
}
}
return result;
}
Multidimensional Array
public static T[][] ToJaggedArray<T>(this IList<T[]> arrays)
{
var result = new T[arrays.Count][];
for (var i = 0; i < arrays.Count; i++)
{
var array = arrays[i];
var length = array.Length;
result[i] = new T[length];
for (var j = 0; j < length; j++)
{
result[i][j] = array[j];
}
}
return result;
}
Usage
var preConvertInts = list.ToJaggedArray();
or
var preConvertInts = list.ToMultiArray();
Update
this IList<T[]> arrays this method is for lists which contain arrays,
to fit OP's example it should be (this IList<List<T>> arrays) – Mong
Zhu
Jagged Array
public static T[][] ToJaggedArray<T>(IList<List<T>> arrays)
{
var result = new T[arrays.Count][];
for (var i = 0; i < arrays.Count; i++)
{
var array = arrays[i];
var length = array.Count;
result[i] = new T[length];
for (var j = 0; j < length; j++)
{
result[i][j] = array[j];
}
}
return result;
}
Multidimensional Array
public static T[,] ToMultiArray<T>(IList<List<T>> arrays)
{
var length = arrays[0].Count;
var result = new T[arrays.Count, length];
for (var i = 0; i < arrays.Count; i++)
{
var array = arrays[i];
if (array.Count != length)
{
throw new ArgumentException("Misaligned arrays");
}
for (var j = 0; j < length; j++)
{
result[i, j] = array[j];
}
}
return result;
}
Note : Totally untested
I have a 2D array of floats and I want to convert it into 1D array of strings, where each string is one row of elements from 2D array. I am not getting output in text file as I expected. Can anyone tell me what I'm doing wrong? It will be great help to me, if somebody could provide efficient code with corrections.
string[] set = new string[240];
string value = "#"
for (int i = 0; i < 240; i++)
{
for (int j = 0; j < 320; j++)
{
value = Convert.ToString(ImageArray[i, j]);
value += ",";
}
set[i] = value + Environment.NewLine;
value = " ";
}
for(int k=0;k<240;k++)
{
System.IO.File.AppendAllText(#"C:\Users\mtech\Desktop\sathya.txt", set[k]);
textBlock1.Text = set[k];
value = " ";
}
inside your inner for loop(j), you are overwriting the value of value variable.
i.e.
for (int j = 0; j < 320; j++)
{
value = Convert.ToString(ImageArray[i, j]);
value += ",";
}
instead of above, you should be doing:
for (int j = 0; j < 320; j++)
{
value += Convert.ToString(ImageArray[i, j]) +",";
}
also, you don't need to perform two nested loops for this task, take a look at String.Join
Here is the shorter way with LINQ:
var allValues = ImageArray.OfType<float>();
string[] lines = new string[240];
for(int i=0; i<240; i++)
{
lines[i] = string.Join(",", allValues.Skip(i*320).Take(320));
}
File.AppendAllLines(#"C:\Users\mtech\Desktop\sathya.txt", lines);
You're re-assigning value in every iteration in your nested for loop. Use the += operator, instead. Another thing you should consider is the use of StringBuilder if you're going to repeatedly append to a string. strings are immutable so you're actually creating a new string every time you append to it.
Not sure if this applies to your case (because of the boundaries in your for loops), but you can use LINQ to flatten a multidimensional array. Example:
float[,] arr = new float[2,2]
{
{123.48F, 45.3F},
{954.23F, 91.3F}
};
var str = string.Join("",
arr.Cast<float>()
.Select(x => Convert.ToString(x) + ","));
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;
}
}
I'm trying to convert a two dimensional string array to a two dimensional int array:
int[][] inner = new int[4][];
string[][] arr = new string[4][]
{
new string[] {"11"},
new string[] {"12"},
new string[] {"21"},
new string[] {"22"}
};
for (int i = 0; i < arr.Length; i++)
{
string name = string.Join(".", arr[i]);
for (int j = 0; j < name.Length; j++)
{
inner[i][j] = Convert.ToInt32(name.Substring(j,1));
}
}
But I'm getting the following exception:
Object reference not set to an instance of an object
at:
inner[i][j] = Convert.ToInt32(name.Substring(j,1));
Change the declaration of your "inner" variable to
int[,] inner = new int[4,2];
I am trying to transfer values from each line of a multi line text box into either a string array or a multidimensional array. I also have 3 multi-line text boxes which need to put into the same array. Below is one of the methods I have been trying:
ParkingTimes[0] = tbxtimeLimitS1.Text;
for (int i = 1; i <= 10; i++)
ParkingTimes[i] = tbxparkingTimesS1.Lines;
ParkingTimes[11] = tbxtimeLimitS2.Lines;
for (int x = 0; x <= 10; x++)
for (int i = 12; i <= 21; i++)
ParkingTimes[i] = tbxparkingTimesS2.Lines;
ParkingTimes[11] = tbxtimeLimitS2.Lines[0];
for (int x = 0; x <= 10; x++)
for (int i = 23; i <= 32; i++)
ParkingTimes[i] = tbxparkingTimesS3.Lines;
What am I doing wrong? Is there a better way to accomplish this?
You can simply do
string[] allLines = textbox.Text.Split('\n');
This will split each line and store the results in the appropriate index in the array. You can then iterate over them like so:
foreach (string text in allLines)
{
//do whatever with text
}
You could use a List instead of a string array
Then the AddRange method could simplify your method eliminatig the foreach loop
List<string> ParkingTimes = new List<string>()
ParkingTimes.Add(tbxtimeLimitS1.Text);
ParkingTimes.AddRange(tbxparkingTimesS1.Lines);
ParkingTimes.AddRange(tbxtimeLimitS2.Lines);
ParkingTimes.AddRange(tbxparkingTimesS2.Lines);
ParkingTimes.AddRange(tbxtimeLimitS2.Lines);
ParkingTimes.AddRange(tbxparkingTimesS3.Lines);
If your code still requires a string array it is possible to get back the array with
string[] myLines = ParkingTimes.ToArray();
An example of this List<string> functionality could be found on MSDN here
You can do something like this:
var totalLines = new List<String>();
totalLines.AddRange( tbxparkingTimesS1.Lines );
totalLines.AddRange( tbxparkingTimesS2.Lines );
totalLines.AddRange( tbxparkingTimesS3.Lines );
if you need it in an array instead of a list, then call:
var array = totalLines.ToArray();
Hope it helps.
This works for me:
string[] textArray = textBox1.Text.Split(new string[] { System.Environment.NewLine }, StringSplitOptions.None);
string[] split = textBox1.Text.Split('\n');
or you can also use:
int srlno=10;
string[] split = new string[srlno];
foreach(string x in textBox1.Lines)
{
split = (split ?? Enumerable.Empty<string>()).Concat(new[] { x }).ToArray();
}