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;
}
}
Related
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];
}
}
I have a problem retrieving values in the order that I want
I wrote a simple code to demonstrate :
List<string> st1 = new List<string>() {"st11","st12"};
List<string> st2 = new List<string>() {"st21","st22"};
ArrayList stringArrayList = new ArrayList();
stringArrayList.Add(st1);
stringArrayList.Add(st2);
string[] n1 = new string[10];
int i = 0;
foreach (List<string> item in stringArrayList)
{
foreach (var item2 in item)
{
n1[i] = item2;
i++;
}
}
in this code the output will be : st11,st12 st21,s22
i want it to get values like this : st11,st21 st12,st22
i want the information stored in this order "st11,st21 st12,st22" into n1
If the lenght of the list are the same you can make something like this:
int j = 0;
int lengthToLoop = st1.length;
for(int i = 0; i < lengthToLoop; i++)
{
n1[j++] = st1[i];
n1[j++] = st2[i];
}
If the length are not equal you can calculate the minimum, copy the minimum length of element from each and then copy the remaining.
Here's an implementation that will do what you're looking for, and will also handle jagged arrays.
List<string> st1 = new List<string>() { "st11", "st12" };
List<string> st2 = new List<string>() { "st21", "st22", };
ArrayList stringArrayList = new ArrayList();
stringArrayList.Add(st1);
stringArrayList.Add(st2);
//this will protect us against differing max indexes if the 2D array is jagged.
int maxIndex = 0;
int totalElements = 0;
foreach (List<string> currentList in stringArrayList)
{
if (currentList.Count > maxIndex)
{
maxIndex = currentList.Count;
}
totalElements += currentList.Count;
}
string[] n1 = new string[totalElements];
int i = 0;
for (int j = 0; j < maxIndex; j++)
{
for (int k = 0; k < stringArrayList.Count; k++)
{
List<string> currentStringArray = (List<string>)stringArrayList[k];
if (j < currentStringArray.Count)
{
n1[i] = currentStringArray[j];
i++;
}
}
}
You have to reverse the two loops, making the outer loop the inner loop.
Use a for loop instead of a foreach loop for the outer loop using the length of the string arrays as the delimiter.
Also: Don't use ArrayList, but a real typed list.
List<string> st1 = new List<string>() { "st11", "st12" };
List<string> st2 = new List<string>() { "st21", "st22" };
List<List<string>> stringArrayList = new List<List<string>>();
stringArrayList.Add(st1);
stringArrayList.Add(st2);
// Get length of first string array
int firstArrayLength = stringArrayList[0].Count;
string[] n1 = new string[10];
int i = 0;
// For each position in the arrays from 0 to firstArrayLength -1 do
for (int arrayPosition = 0; arrayPosition < firstArrayLength; arrayPosition++)
{
// For each of the string array
foreach (var stringArray in stringArrayList)
{
// Get the item from the stringArray at position arrayPosition
n1[i] = stringArray[arrayPosition];
i++;
}
}
First, check the max list length, and then take item at index (0,1,3... till max) from every list. Don't forget to check if the index exist. In addition, you can set the exact size of n1 because it is the sum of all list count. You don't need to have a separated line for i++ in this case.
List<string> st1 = new List<string> { "st11", "st12" };
List<string> st2 = new List<string> { "st21", "st22" };
List<List<string>> stringArrayList = new List<List<string>> {st1, st2};
int maxCount = stringArrayList.Max(x => x.Count);
int totalItems = 0;
stringArrayList.ForEach(x=> totalItems+= x.Count);
string[] n1 = new string[totalItems];
int i = 0;
for (int index = 0; index < maxCount; index++)
{
foreach (var list in stringArrayList)
{
if (list.Count > index)
{
n1[i++] = list[index];
}
}
}
to convert a list to array[,] there is code:
double[,] arr = new double[list.Count, list[0].Length];
for (int i = 0; i < list.Count; i++)
{
for (int j = 0; j < list[0].Length; j++)
{
arr[i, j] = list[i][j];
}
}
I want to convert it to flatten array so Using the fact
Flattened array index computation
array[(Y coordinate * width) + X coordinate]
2D array index computation
array[Y coordinate, X coordinate]
code changes to
double[] arr = new double[list.Count * list[0].Length];
for (int i = 0; i < list.Count ; i++)
{
for (int j = 0; j < list[0].Length; j++)
{
arr[i] = list[i * list[0].Length + j];
}
}
But What would be the code to convert a List < List < double > > to flatten array?
Is it possible to do it in 2 loops as the above code?
the List<List<double>> represents a double[,] arr
Honestly I'm not 100% sure what you're asking, but to flatten a List<List<>> you can use SelectMany from Linq, here's a simple example:
static void Main(string[] args)
{
var first = new List<double> {1, 2, 3};
var second = new List<double> { 3, 4, 5 };
var lists = new List<List<double>> {first, second};
var flatten = lists.SelectMany(a => a).ToArray();
foreach (var i in flatten)
{
Console.WriteLine(i);
}
}
Given the fact that your list ist a nested enumerable you can simply use Linq.
double[] array = nestedList.SelectMany(a => a).ToArray();
In a loop (i.e. without LINQ) would be something like
public static void Main()
{
List<List<double>> listOfLists = new List<List<double>>();
listOfLists.Add(new List<double>() { 1, 2, 3 });
listOfLists.Add(new List<double>() { 4, 6 });
int flatLength = 0;
foreach (List<double> list in listOfLists)
flatLength += list.Count;
double[] flattened = new double[flatLength];
int iFlat = 0;
foreach (List<double> list in listOfLists)
foreach (double d in list)
flattened[iFlat++] = d;
foreach (double d in flattened)
Console.Write("{0} ", d);
Console.ReadLine();
}
I have the following array:
string[] list1 = new string[2] { "01233", "THisis text" };
string[] list2 = new string[2] { "01233", "THisis text" };
string[] list3 = new string[2] { "01233", "THisis text" };
string[] list4 = new string[2] { "01233", "THisis text" };
string[][] lists = new string[][] { list1, list2, list3, list4 };
I am trying to see the array values using the following code:
for (int i = 0; i < lists.GetLength(0); i++)
{
for (int j = 0; j < lists.GetLength(1); j++)
{
string s = lists[i, j]; // the problem is here
Console.WriteLine(s);
}
}
Console.ReadLine();
The problem is lists[i, j]; is underlined and causing this error message : Wrong number of indices inside []; expected '1'
Could you please tell me how to solve this problem ?
lists is not a 2D array. It is an array of arrays. Hence the syntax lists[i][j].
for (int i = 0; i < lists.Length; i++)
{
for (int j = 0; j < lists[i].Length; j++)
{
string s = lists[i][j]; // so
Console.WriteLine(s);
}
}
Console.ReadLine();
Note how Length is checked for an array of arrays. However, as others have said, why not use foreach? You need two nested foreach loops for an array of arrays.
Another option is to actually use a 2D array, a string[,]. Declared like:
string[,] lists = { { "01233", "THisis text" },
{ "01233", "THisis text" },
{ "01233", "THisis text" },
{ "01233", "THisis text" }, };
Then you can use two for loops like you have, with lists[i,j] syntax, or one single foreach.
Because you have list of lists and not 2D array. To get element from your datastructure you have to use it like this:
lists[i][j]
and your full code would be:
for (int i = 0; i < lists.Length; i++)
{
for (int j = 0; j < lists[i].Length; j++)
{
string s = lists[i][j];
Console.WriteLine(s);
}
}
Console.ReadLine();
But actually, in your case it's better to use foreach:
foreach (var l in lists)
{
foreach (var s in l)
{
Console.WriteLine(s);
}
}
Console.ReadLine();
Try to use this
for (int i = 0; i < lists.Length; i++)
{
for (int j = 0; j < lists[i].Length; j++)
{
string s = lists[i][j];
Console.WriteLine(s);
}
}
Console.ReadLine();
Use foreach instead
foreach(var array in lists )
foreach(var item in array)
{
//item
}
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();
}