You have given a string like "(32+5)*20" and you need to create a list with all chars, but need to merge the numbers to one entry like "32" and "20". How to do it?
I have already tried
string formel = "(32+5)*20";
char[] zeichen = formel.ToCharArray();
var liste = new List<string>();
for(int i = 0; i < zeichen.Length ; i++)
{
if(Char.IsNumber(zeichen[i]) && formel.Substring(i, i + 1).Any(char.IsNumber))
{
liste.Add(zeichen[i].ToString() + zeichen[i+1].ToString());
}
else
{
liste.Add(zeichen[i].ToString());
}
}
You could use regex to return the groups of numbers:
var formel = "(32+5)*20";
var pattern = "([0-9]+)";
var match = Regex.Match(formel, pattern);
and then use
match.Groups
The list as posted will still contain the same number of elements as the string did, since you added to it on every loop iteration. To "merge" into one entry, you need to not add on some iterations, but instead add that digit to the previous number.
This is easier if you check if the previous item was a number, rather than the next.
for (int i = 0; i < zeichen.Length; i++)
{
if (i > 0 && Char.IsNumber(zeichen[i]) && Char.IsNumber(zeichen[i - 1])) // if got a number, and had a number before
{
// Then dont Add to the list, instead add to the number/string
liste[list.Count - 1] += zeichen[i];
//liste.Add(zeichen[i].ToString() + zeichen[i + 1].ToString());
}
else
liste.Add(zeichen[i].ToString());
}
// "(", "32", "+", "5", ")", "*", "20"
You can do it by using Regex and LINQ
var dateText = "(32 + 5) * 20";
string splitPattern = #"[^\d]";
var result = Regex.Split(dateText, splitPattern).Where(x=>x!="");
I hope this will help you #Janic
Hi i want to search for character in a string array but i need to search Between 2 indices. For example between index 2 and 10. How can I do that?
foreach (var item in currentline[2 to 10])
{
if (item == ',' || item == ';')
{
c++;
break;
}
else
{
data += item;
c++;
}
}
As you can see, foreach enumerates over a collection or any IEnumerable.
As the comments say, you can use a for loop instead, and pick out the elements you want.
Alternatively, since you want to search for a character in a string, you can use IndexOf, using the start index and count overload to find where a character is.
As there is no use of the c++ in your code I will assume that it's a vestige of code.
You can simply addess your issue like this:
In the currentline
Take char from index 2 to 10
Till you find a char you don't want.
concatenate the resulting char array to a string.
Resulting Code:
var data = "##";//01234567891 -- index for the string below.
var currentline= "kj[abcabc;z]Selected data will be between: '[]';";
var exceptChar = ",;";
data += new string(
input.Skip(3)
.Take(8)
.TakeWhile(x=> !exceptChar.Contains(x))
.ToArray()
);
There is a string method called string.IndexOfAny() which will allow you to pass an array of characters to search for, a start index and a count. For your example, you would use it like so:
string currentLine = ",;abcde;,abc";
int index = currentLine.IndexOfAny(new[] {',', ';'}, 2, 10-2);
Console.WriteLine(index);
Note that the last parameter is the count of characters to search starting at the specified index, so if you want to start at index 2 and finish at index 10, the count will be finish-start, i.e. 10-2.
You can search for characters in strings and get their indexes with this LINQ solution:
string str = "How; are, you; Good ,bye";
char[] charArr = { ',', ';' };
int startIndex = 2;
int endIndex = 10;
var indexes = Enumerable.Range(startIndex, endIndex - startIndex + 1)
.Where(i=>charArr.Contains(str[i]))
.ToArray();
In this case we get Enumerable.Range(2, 9) which generates a sequence between 2 and 10 and the Where clause filters the indexes of the characters in str that are matching one of the characters inside charArr.
Thanks everey one finaly i fixed it by your guid thanks all
myarr = new mytable[50];
number_of_records = 0;
number_of_records = fulllines.Length;
for (int line = 1; line < fulllines.Length; line++)
{
int c = 0;
for (int i = 0; i < record_lenth; i++)
{
string data = "";
string currentline = fulllines[line];
string value = "";
for (int x = c; x < fulllines[line].Length; x++)
{
value += currentline[x];
}
foreach (var item in value)
{
if (item == ',' || item == ';')
{
c++;
break;
}
else
{
data += item;
c++;
}
}
}
}
I have a list of names and I loop through them to create a comma separated list in a string variable (Bob, George, Will, Terry).
I need the list to eventually look like (Bob, George, Will and Terry).
How do I find the LAST instance of the comma and replace it with the word "and"? Once I find the LAST instance, I think it's a simple matter of doing something like
string new=ori.Substring(0,start) + rep + ori.Substring(start+rep.Length);
Thoughts? Comments? Suggestions?
Thanks,
Bob
This should work for you. Added the alternative comma style as well.
var names = "Bob, George, Will, Terry";
var lastCommaPosition = names.LastIndexOf(',');
if (lastCommaPosition != -1)
{
names = names.Remove(lastCommaPosition, 1)
//.Insert(lastComma, " and");
.Insert(lastCommaPosition, ", and");
}
Console.WriteLine(names);
You can use a combination of LINQ and String.Join. This solution does not need the last index of a comma and is "more fluent" to read.
var list = new List<string> { "Bob", "George", "Will", "Terry" };
var listAsString = list.Count > 1
? string.Join(", ", list.Take(list.Count - 1)) + " and " + list.Last()
: list.First();
You can use Linq,
list.Select(i => i).Aggregate((i, j) => i + (list.IndexOf(j) == list.Count -1 ? " and " : " , ") + j);
Hope helps,
This should do the trick for you:
var foo = "Bob, George, Will, Terry";
if (foo.Contains(",")) {
foo = foo.Substring(0, foo.LastIndexOf(",")) + " and" + foo.Substring(foo.LastIndexOf(",")+ 1);
}
I'm not sure what you wanted to do, but the following code works:
string original = "(Bob, George, Will, Terry)";
string result = "";
string[] splited = original.Split(',');
for (int i = 0; i < splited.Count(); i++)
{
if(i == splited.Count() - 2)
{
result += splited[i] + " and";
}
else if(i == splited.Count() - 1)
{
result += splited[i];
}
else
{
result += splited[i] + ",";
}
}
I Used split to split the original string in a vector so i worked with this vector to replace the last comma to the word "and".
Please someone to help me to parse these sample string below? I'm having difficulty to split the data and also the data need to add carriage return at the end of every event
sample string:
L,030216,182748,00,FF,I,00,030216,182749,00,FF,I,00,030216,182750,00,FF,I,00
batch of events
expected output:
L,030216,182748,00,FF,I,00 - 1st Event
L,030216,182749,00,FF,I,00 - 2nd Event
L,030216,182750,00,FF,I,00 - 3rd Event
Seems like an easy problem. Something as easy as this should do it:
string line = "L,030216,182748,00,FF,I,00,030216,182749,00,FF,I,00,030216,182750,00,FF,I,00";
string[] array = line.Split(',');
StringBuilder sb = new StringBuilder();
for(int i=0; i<array.Length-1;i+=6)
{
sb.AppendLine(string.Format("{0},{1} - {2} event",array[0],string.Join(",",array.Skip(i+1).Take(6)), "number"));
}
output (sb.ToString()):
L,030216,182748,00,FF,I,00 - number event
L,030216,182749,00,FF,I,00 - number event
L,030216,182750,00,FF,I,00 - number event
All you have to do is work on the function that increments the ordinals (1st, 2nd, etc), but that's easy to get.
This should do the trick, given there are no more L's inside your string, and the comma place is always the sixth starting from the beginning of the batch number.
class Program
{
static void Main(string[] args)
{
String batchOfevents = "L,030216,182748,00,FF,I,00,030216,182749,00,FF,I,00,030216,182750,00,FF,I,00,030216,182751,00,FF,I,00,030216,182752,00,FF,I,00,030216,182753,00,FF,I,00";
// take out the "L," to start processing by finding the index of the correct comma to slice.
batchOfevents = batchOfevents.Substring(2);
String output = "";
int index = 0;
int counter = 0;
while (GetNthIndex(batchOfevents, ',', 6) != -1)
{
counter++;
if (counter == 1){
index = GetNthIndex(batchOfevents, ',', 6);
output += "L, " + batchOfevents.Substring(0, index) + " - 1st event\n";
batchOfevents = batchOfevents.Substring(index + 1);
} else if (counter == 2) {
index = GetNthIndex(batchOfevents, ',', 6);
output += "L, " + batchOfevents.Substring(0, index) + " - 2nd event\n";
batchOfevents = batchOfevents.Substring(index + 1);
}
else if (counter == 3)
{
index = GetNthIndex(batchOfevents, ',', 6);
output += "L, " + batchOfevents.Substring(0, index) + " - 3rd event\n";
batchOfevents = batchOfevents.Substring(index + 1);
} else {
index = GetNthIndex(batchOfevents, ',', 6);
output += "L, " + batchOfevents.Substring(0, index) + " - " + counter + "th event\n";
batchOfevents = batchOfevents.Substring(index + 1);
}
}
output += "L, " + batchOfevents + " - " + (counter+1) + "th event\n";
Console.WriteLine(output);
}
public static int GetNthIndex(string s, char t, int n)
{
int count = 0;
for (int i = 0; i < s.Length; i++)
{
if (s[i] == t)
{
count++;
if (count == n)
{
return i;
}
}
}
return -1;
}
}
Now the output will be in the format you asked for, and the original string has been decomposed.
NOTE: the getNthIndex method was taken from this old post.
If you want to split the string into multiple strings, you need a set of rules,
which are implementable. In your case i would start splitting the complete
string by the given comma , and than go though the elements in a loop.
All the strings in the loop will be appended in a StringBuilder. If your ruleset
say you need a new line, just add it via yourBuilder.Append('\r\n') or use AppendLine.
EDIT
Using this method, you can also easily add new chars like L or at the end rd Event
Look for the start index of 00,FF,I,00 in the entire string.
Extract a sub string starting at 0 and index plus 10 which is the length of the characters in 1.
Loop through it again each time with a new start index where you left of in 2.
Add a new line character each time.
Have a try the following:
string stream = "L,030216,182748,00,FF,I,00, 030216,182749,00,FF,I,00, 030216,182750,00,FF,I,00";
string[] lines = SplitLines(stream, "L", "I", ",");
Here the SplitLines function is implemented to detect variable-length events within the arbitrary-formatted stream:
string stream = "A;030216;182748 ;00;FF;AA;01; 030216;182749;AA;02";
string[] lines = SplitLines(batch, "A", "AA", ";");
Split-rules are:
- all elements of input stream are separated by separator(, for example).
- each event is bounded by the special markers(L and I for example)
- end marker is previous element of event-sequence
static string[] SplitLines(string stream, string startSeq, string endLine, string separator) {
string[] elements = stream.Split(new string[] { separator }, StringSplitOptions.RemoveEmptyEntries);
int pos = 0;
List<string> line = new List<string>();
List<string> lines = new List<string>();
State state = State.SeqStart;
while(pos < elements.Length) {
string current = elements[pos].Trim();
switch(state) {
case State.SeqStart:
if(current == startSeq)
state = State.LineStart;
continue;
case State.LineStart:
if(++pos < elements.Length) {
line.Add(startSeq);
state = State.Line;
}
continue;
case State.Line:
if(current == endLine)
state = State.LineEnd;
else
line.Add(current);
pos++;
continue;
case State.LineEnd:
line.Add(endLine);
line.Add(current);
lines.Add(string.Join(separator, line));
line.Clear();
state = State.LineStart;
continue;
}
}
return lines.ToArray();
}
enum State { SeqStart, LineStart, Line, LineEnd };
f you want to split the string into multiple strings, you need a set of rules, which are implementable. In your case i would start splitting the complete string by the given comma , and than go though the elements in a loop. All the strings in the loop will be appended in a StringBuilder. If your ruleset say you need a new line, just add it via yourBuilder.Append('\r\n') or use AppendLine.
if I have a foreach loop that takes a whole bunch of addresses and loops through them, is there a way I could skip the first 500 entries,
something like:
foreach(var row in addresses)
{
string strAddr = row.ADDRESS + "," + row.CITY + "," + row.ST;
System.Threading.Thread.Skip(500)
}
I know skip doesn't exist but is there anything I can use that would do the same thing?
You can use a method with a meaningful name:
foreach(var row in addresses.Skip(500))
{
// ...
}
You need to add using System.Linq; since it's a LINQ extension method.
If the type of addresses doesn't implement the generic IEnumerable<T> interface you could use Cast<T>. For example (presuming the type is Address):
foreach(var row in addresses.Cast<Address>().Skip(500))
{
// ...
}
You can use the Skip extension method:
foreach(var row in addresses.Skip(500))
{
string strAddr = row.ADDRESS + "," + row.CITY + "," + row.ST;
}
Or, if addresses is just an array or list:
for (int i = 500 ; i < addresses.Count ; i++) // assuming addresses is a List<T>
{
var row = addresses[i];
string strAddr = row.ADDRESS + "," + row.CITY + "," + row.ST;
}
Use the Enumerator interface directly: http://msdn.microsoft.com/en-us/library/system.collections.ienumerator(v=vs.110).aspx
var enumerator = addresses.GetEnumerator();
for (var i = 0; i < 300 && enumerator.MoveNext(); i++);
A feasible and fast solution would be to use LINQ Skip method to iterate over a subset of the collection starting from the 500th element of the collection.
foreach (var row in addresses.Skip(500))
{
// do your stuff...
}