I am trying to create a string and below is the thing which i am trying to achieve:
String first = "Previous.value1 | Previous.value2";
String second = "New.value1| New.value2";
I am trying to create final string like this:
string final ="generate Previous.value1 cross New.value1 ? Previous.value1 cross New.value2";
But problem is when i will have mismatch like below:
String first = "Previous.value1 | Previous.value2";
String second = "New.value1";
Then i want to have like this because i dont have matching value for Previous.Value2 in second variable:
string final ="generate Previous.value1 cross New.value1";
So far i am successfully in generating final string when i have same count of value in both the string.
string final = "generate";
if (first.Split('|').Count() - second.Split('|').Count() == 0)
{
int i = 0;
foreach (var item in first.Split('|').Count())
{
if (i == 0)
final = final + item + " cross " + second.Split('|')[i];
else
final = final + " ? " + item + " cross " + second.Split('|')[index];
i++;
}
}
Try this LINQ query (using the Zip extension method):
var zippedQry = first.Split('|').Zip(second.Split('|'),
(f, s) => f.Trim() + " cross " + s.Trim());
string final = "generate " + String.Join(" ? ", zippedQry.ToArray());
To remain in the style that you use, I would suggest to first split both strings
String first = "Previous.value1 | Previous.value2";
String second = "New.value1 | New.value2";
string final = "generate ";
string[] first_values = first.Split('|');
string[] second_values = second.Split('|');
Then you can just orient yourself on the shortest array. If you have in the second_values not enough corresponding values for the first_values you collect only the corresponding ones. Using a normal for-loop:
// run until the length of the shortest one
for (int i = 0; i < Math.Min(first_values.Length, second_values.Length); i++)
{
// bild the normal cross-version for the first position
string sentence = first_values[i] + " cross " + second_values[i];
// if on first position use normal version otherwise put a ? infront of it
final += i == 0 ? sentence : " ? " + sentence;
}
This loop should handle also string like this:
String first = "Previous.value1 | Previous.value2 | Previous.value3 | Previous.value4";
String second = "New.value1 | New.value2 | New.value3";
Related
My main code is below:
Mtb.Application MtbApp = new Mtb.Application();
MtbApp.UserInterface.Visible = true;
MtbApp.UserInterface.DisplayAlerts = false;
Mtb.Project MtbProj = MtbApp.ActiveProject;
Mtb.Columns MtbColumns;
Mtb.Column MtbColumn1;
Double[] data1;
Hashtable htSingleColumn;
List<double> listSingleColumn;
int i = 1 ;
foreach (DictionaryEntry de in htDataTable)
{
htSingleColumn = (Hashtable)de.Value;
listSingleColumn = (List<double>)htSingleColumn["listSingleData"];
data1 = listSingleColumn.ToArray();
MtbColumns = MtbProj.ActiveWorksheet.Columns;
MtbColumn1 = MtbColumns.Add(null, null, i);
MtbColumn1.SetData(data1);
// strLowlim and strUpplim have no influence on this issue here
strCommand = "Capa C" + i+" 1;" + ((strLowlim == "NA") ? "" : (" Lspec " + strLowlim + ";")) +((strUpplim == "NA") ? "" : (" Uspec " + strUpplim + ";"))+ " Pooled; AMR; UnBiased; OBiased; Toler 6; Within; Percent; CStat.";
// The program is crashing here as a result of the columns not being created sequentially
MtbProj.ExecuteCommand(strCommand);
Mtb.Graph MtbGraph = MtbProj.Commands.Item(i).Outputs.Item(1).Graph;
MtbGraph.SaveAs("C:\\MyGraph" + DateTime.Now.ToString("yyyy-MM-dd HHmmss"), true, Mtb.MtbGraphFileTypes.GFPNGHighColor);
i++;
}
MtbApp.Quit();
When running this code (with the crashing section commented out), I get the following output:
It should look like this:
I am really puzzled about this result. The variable i is right, but what is affecting the column number?
I can't find much information on the Web about Minitab. I just read the start guide here.
This line is the problem.
MtbColumn1 = MtbColumns.Add(null, null, i);
The third parameter Quantity specifies the number of columns to add. On the first iteration of the loop, you add i = 1 column, but on the second iteration of the loop you add i = 2 columns. Each iteration of the loop will add an additional i columns, when what you really want is to add one column each time.
Change the line to:
MtbColumn1 = MtbColumns.Add();
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".
I'm generating a list of from/to coordinate points, together with the distance/time between those points.
For illustration: the header of the end product looks like this
writer.WriteLine("fromX" + ";" + "fromY" + ";" + "toX" + ";" + "toY" + ";" + "distance" + ";" + "time");
The process of calculating from point to point is as follows:
A -> A
A -> B
A -> C
..
B -> A
B -> B
B -> C
etc
The distance and time are per-calculated and are situated in a separate file. However, each line in this file consists of the distance/time between the same start point and every endpoint, thus for example:
0;0;11289;950;9732;899;9886;725;32893;2195;38010;2478;46188;3330;
The goal is to have the following notation in the end product:
point A;point A;0;0
point A;point B;11289;950
point A;point C;9732;899
etc.
As you can see, I would need to split the distance + time line at every 2nd value.
At the moment, I have the following code:
List<string> locationsList = new List<string>();
using (var reader = new StreamReader(File.OpenRead("locations.csv")))
{
while (reader.Peek() != -1)
locationsList.Add(reader.ReadLine());
}
List<string> distanceTime = new List<string>();
using (var reader = new StreamReader(File.OpenRead("distance.csv")))
{
while (reader.Peek() != -1)
distanceTime.Add(reader.ReadLine());
}
using (var writer = new System.IO.StreamWriter("Output.csv"))
{
writer.WriteLine("fromX" + ";" + "fromY" + ";" + "toX" + ";" + "toY" + "distance" + ";" + "time")
foreach (var fromLine in locationsList)
{
splitFrom = fromLine.Split(';');
fromX = splitFrom[0].Trim();
fromY = splitFrom[1].Trim();
foreach (var toLine in locationsList)
{
splitTo = toLine.Split(';');
toX = splitTo[0].Trim();
toY = splitTo[1].Trim();
writer.WriteLine(fromX + ";" + fromY + ";" + toX + ";" + toY);
}
}
MessageBox.Show("Done");
}
This would have to be expanded with probably a foreach loop that reads a line from the distanceTime-list, splits it, takes every first 2 values and writes them together with the start -and end point.
Problem is that I have no idea how to split after every 2nd value.
Do you have any suggestions?
You don't really need to split on every second ';', you just need a slightly different for loop:
using System;
class Program {
static void Main(string[] args) {
string line = "0;0;11289;950;9732;899;9886;725;32893;2195;38010;2478;46188;3330;";
string[] values = line.Split(';');
char pointName = 'A';
for (int i = 0; i < values.Length - 1; i += 2) {
string endProductLine = string.Format("point A;point {0};{1};{2}", pointName, values[i], values[i + 1]);
Console.WriteLine(endProductLine);
pointName++;
}
}
}
https://msdn.microsoft.com/en-us/library/0w4e0fzs.aspx
Use the % operator:
string coords = "0;0;11289;950;9732;899;9886;725;32893;2195;38010;2478;46188;3330;";
string[] values = coords.Split(';');
for(int val=0; val<values.Length; val++)
{
int coord;
if(val % 2 == 0)
{
//this will give you access to every second value
int.TryParse(values[val], out coord);
Console.WriteLine(coord.ToString());
}
}
how can i get string between two dots for example ?
[Person.Position.Name]
for this case I want to get the string "Position"
I can also have three dots ….
[Person.Location.City.Name]
I want to take all strings between dots
I know it's a year old question, but the other answers are not sufficient, like they are even pretending that you want "Location.City" because they don't know how to seperate them.. The solution is simple though, don't use indexof.
say you want to seperate the Four (not 3) parts:
String input = "Person.Location.City.Name"
string person = input.Split('.')[0];
string location = input.Split('.')[1];
string city = input.Split('.')[2];
string name = input.Split('.')[3];
Console.WriteLine("Person: " + person + "\nLocation: " + location + "\nCity: " + city + "\nName: " + name);
This might help you:
string s = "Person.Position.Name";
int start = s.IndexOf(".") + 1;
int end = s.LastIndexOf(".");
string result = s.Substring(start, end - start);
It will return all the values between the first and the last dot.
If you don't want the result with dot between the strings, you can try this:
string s = "Person.Location.Name";
int start = s.IndexOf(".") + 1;
int end = s.LastIndexOf(".");
var result = s.Substring(start, end - start).Split('.');
foreach (var item in result)
{
//item is some string between the first and the last dot.
//in this case "Location"
}
Try this
string str = "[Person.Location.City.Name]";
int dotFirstIndex = str.IndexOf('.');
int dotLastIndex = str.LastIndexOf('.');
string result = str.Substring((dotFirstIndex + 1), (dotLastIndex - dotFirstIndex) - 1); // output Location.City
When I run this through the debugger the result for string CL_S and string NA_S are the same value, which is 122.13.
Not sure why it does this since the indexOf is different - the second one does not exist.
text = "4R|1|^^^100^CL_S|122.13|38||||F|||20070628114638"
string str = text;
try
{
int a_first = str.IndexOf("^^^100") + "^^^100".Length + 1;
string str_a = str.Substring(a_first);
string[] words_a = str_a.Split('|');
string CL_S = words_a[1];
int b_first = str.IndexOf("^^^101") + "^^^101".Length + 1;
string str_b = str.Substring(b_first);
string[] words_b = str_b.Split('|');
string NA = words_b[1];
Step through a debugger and look at the values of the variables.
Here's a quick analysis which should help point you towards the problem:
a_first has the value 12
str_a has the value "CLS_S|122.13|..."
b_first has the value 6 (Note that you are adding -1 + 6 + 1; the -1 is from the IndexOf that doesn't have a match. IndexOf is working just fine.)
str_b has the value "^^100^CL_S|122.13|..."
When you split either str_a or str_b on a |, the second element (index [1]) of both will be 122.13.
In the second case the IndexOf call returns -1, and adding seven to that puts you at index 6.
When you use that in the Substring call you will get ^^100^ prefixed to the string, compared to the string from the first case.
As that doesn't contain any | characters, splitting will only give a different result for the first item in the array, and as you are getting the second item it will be the same as in the first case.
Run this on IDEONE https://ideone.com/F6KDNS
using System;
public class Test
{
public static void Main()
{
string str = "4R|1|^^^100^CL_S|122.13|38||||F|||20070628114638" ;
int a_first = str.IndexOf("^^^100") + "^^^100".Length + 1;
string str_a = str.Substring(a_first);
string[] words_a = str_a.Split('|');
string CL_S = words_a[1];
Console.WriteLine(a_first);
Console.WriteLine(str_a);
Console.WriteLine(CL_S);
Console.WriteLine();
int b_first = str.IndexOf("^^^101") + "^^^101".Length + 1;
string str_b = str.Substring(b_first);
string[] words_b = str_b.Split('|');
string NA = words_b[1];
Console.WriteLine(b_first);
Console.WriteLine(str_b);
Console.WriteLine(NA);
}
}
I got this:
12
CL_S|122.13|38||||F|||20070628114638
122.13
6
^^100^CL_S|122.13|38||||F|||20070628114638
122.13
So you can see that the second IndexOf returns -1 => b_first is 6. This means that you the two strings in both have their first break at
CL_S| & ^^100^CL_S|
And thus both have second item = 122.13