Getting only the last entry on counting - c#

I'm only getting the last entry of the counting typed like this
public string ZodziuSkaiciavimas()
{
foreach (var sentence in Sakiniai.TrimEnd('.').Split('.'))
{
Rezultatas=(eilute.ToString() + " sakinyje zodziu:" + (sentence.Trim().Split(' ').Count() + sentence.Trim().Split('-').Count() + sentence.Trim().Split(';').Count() + sentence.Trim().Split(':').Count() + sentence.Trim().Split(',').Count() - 4));
eilute++;
}
return Rezultatas;
And I need to get the answer with a return type.
If I type code like this than i get what i want,but no returns.
public string ZodziuSkaiciavimas()
{
foreach (var sentence in Sakiniai.TrimEnd('.').Split('.'))
{
Console.WriteLine(eilute.ToString() + " sakinyje zodziu:" + (sentence.Trim().Split(' ').Count() + sentence.Trim().Split('-').Count() + sentence.Trim().Split(';').Count() + sentence.Trim().Split(':').Count() + sentence.Trim().Split(',').Count() - 4));
eilute++;
}
return Rezultatas;
}

Why arent you appending your results as below
Rezultatas +=(eilute.ToString() + " sakinyje zodziu:" + (sentence.Trim().Split(' ').Count() + sentence.Trim().Split('-').Count() + sentence.Trim().Split(';').Count() + sentence.Trim().Split(':').Count() + sentence.Trim().Split(',').Count() - 4)) + "\n";

It looks like you want to return multiple numbers from your method, but Rezultatas is a single string. You can fix it by changing the return type to List<int>, and returning a list:
public List<int> ZodziuSkaiciavimas() {
var Rezultatas = new List<int>()
foreach (var sentence in Sakiniai.TrimEnd('.').Split('.')) {
var res = sentence.Trim().Split(' ', '-', ';', ':', ',').Length;
Rezultatas.Add(res);
}
return Rezultatas;
}
When the callers decide to print the Rezultatas they gets back from your method, they could decide what character to put between the numbers (say, a comma ',') and print it like this:
var numbers = ZodziuSkaiciavimas();
Console.WriteLine(string.Join(", ", numbers));

Related

Unexpected result while generating string with Aggregate() in linq

FIDDLE
Utility Function:
public static string GetProperties<T>(string alias="")
{
if (alias.Length>0)
{
return typeof(T).GetProperties().Select(x => x.Name).Aggregate((x, y) =>
alias + " = " + alias + "." + x + "," + Environment.NewLine + alias + " = " + alias + "." + y + ",");
}
else
{
return typeof(T).GetProperties().Select(x => x.Name).Aggregate((x, y) => x + Environment.NewLine + y);
}
}
Code:
public class ContainerInLog
{
public int ContainerInLogID { get; set; }
public int ContainerInID { get; set; }
public int CargoID { get; set; }
public int LoadStatus { get; set; }
}
public static void Main()
{
string list = GetProperties<ContainerInLog>("y");
Console.WriteLine(list);
}
Result:
y = y.y = y.y = y.ContainerInLogID,
y = y.ContainerInID,,
y = y.CargoID,,
y = y.LoadStatus,
Expected Result:
ContainerInLogID = y.ContainerInLogID,
ContainerInID = y.ContainerInID,
CargoID = y.CargoID,
LoadStatus = y.LoadStatus,
If you are really stuck on returning the entire concatenated string instead of returning an enumerable of them, I wouldn't use Aggregate here, just use string.Join. Also, you can simplify the statement by crafting the string inside the Select. For example:
return string.Join(
Environment.NewLine,
typeof(T)
.GetProperties()
.Select(x => $"{x.Name} = {alias}.{x.Name},"));
Bonus: If you change the separator to $",{Environment.NewLine}" you can remove the inline comma and you won't get the final comma on the end of your string (example fiddle).
#DavidG has the nicer solution here, but whats going wrong with your aggregation is the following:
.Aggregate((x, y) =>
alias + " = " + alias + "." + x + "," + Environment.NewLine + alias + " = " + alias + "." + y + ",");
The Aggregate selector function (your (x,y)) takes the following form:
Func<TAccumulate,TResult> resultSelector
That means in your case, x is the accumulated aggregate result already, eg "ContainerInLogID = y.ContainerInLogID".
But to make the next aggregate, you transform x again: alias + " = " + alias + "." + x, making "y = y.y = y.ContainerInLogID". And so on for each following property, each one adding another prefix of "y = y.".

Method name expected displaying strings in label c#

I am trying to add a specific part of a string to a label in c#
I only want the string up to the space to be displayed (in line 6 of this code)
bool BoolSpace = s.Contains(" ");
if (BoolSpace == true)
{
int IntSpacePos = s.IndexOf(" ");
int StrPos = IntSpacePos - 1;
LblLmcCode1.Text = LblLmcCode1.Text + s(0, StrPos);
}
else
{
LblLmcCode2.Text = LblLmcCode2.Text + '\n' + s;
}
However line 6 is returning an error method name expected about the 's' of s(0, StrPos)
You should use Substring method:
s.Substring(0, StrPos);
All together with fewer lines:
LblLmcCode1.Text = LblLmcCode1.Text + s.Substring(0, s.IndexOf(" ") - 1);
Also as BoolSpace is a boolean itself no need to check if it is equal to true but it is enough to write if(BoolSpace), and better still just place the Contains in the statement:
if(s.Contains(" "))
{
LblLmcCode1.Text = LblLmcCode1.Text + s.Substring(0, s.IndexOf(" ") - 1);
}
else
{
LblLmcCode2.Text = LblLmcCode2.Text + '\n' + s;
}

String substitution in 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".

C#, Split after 2 ;'s in same line

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());
}
}

Data lost while adding string to listbox

I am cycling through the contents of a two-dimensional array containing the result of a Punnett Square calculation for gene crosses. I need to summarize the result so that the user can readily see the unique instances. I can accomplish this by putting the result into a text box, but when I try and use a ListBox to display the data, part of the information is getting lost, namely a translation of the AaBBCc type data to something that directly relates to the traits that the user initially selected.
This is the main block of code for the operation:
foreach (string strCombination in arrUniqueCombinations)
{
int intUniqueCount = 0;
decimal decPercentage;
foreach (string strCrossResult in arrPunnettSQ)
{
if (strCrossResult == strCombination)
{
intUniqueCount++;
}
}
decPercentage = Convert.ToDecimal((intUniqueCount*100)) / Convert.ToDecimal(intPossibleCombinations);
txtReport.AppendText(strCombination + " appears " + intUniqueCount.ToString() + " times or " + decPercentage.ToString() + "%."+ Environment.NewLine);
lstCrossResult.Items.Add(DecodeGenome(strCombination) + " appears " + intUniqueCount.ToString() + " times or " + decPercentage.ToString() + "%.");
}
For appending the data to the textbox I use this code and it works perfectly:
txtReport.AppendText(DecodeGenome(strCombination) + " appears " + intUniqueCount.ToString() + " times or " + decPercentage.ToString() + "%."+ Environment.NewLine);
Giving the result:
Trait 1 Het.,Trait 3 appears 16 times or 25%.
For adding the result to a list box, this works:
lstCrossResult.Items.Add(strCombination + " appears " + intUniqueCount.ToString() + " times or " + decPercentage.ToString() + "%.");
Giving the result:
AaBBCc appears 16 times or 25%.
But the contents of strCombination is AaBBCc and I need it translated to "Trait 1 Het.,Trait 3", which I accomplish with this bit of code:
private string DecodeGenome(string strGenome)
{
string strTranslation = "";
int intLength = strGenome.Length;
int intCounter = intLength / 2;
string[] arrPairs = new string[intLength / 2];
//Break out trait pairs and load into array
for (int i = 1; i <= intLength; i++)
{
arrPairs[i / 2] = strGenome.Substring((i-1),2);
i++;
}
foreach (string strPair in arrPairs)
{
char chFirstLetter = strPair[0];
char chSecondLetter = strPair[1];
intCounter = intCounter - 1;
if (Char.IsUpper(chFirstLetter))
{
if (!Char.IsUpper(chSecondLetter))
{
if (intCounter > 0)
{
txtReport.AppendText(GetDescription(strPair.Substring(0, 1)) + " Het.,");
}
else
{
txtReport.AppendText(GetDescription(strPair.Substring(0, 1)));
}
}
}
else
{
if (!Char.IsUpper(chSecondLetter))
{
if (intCounter > 0)
{
txtReport.AppendText(GetDescription(strPair.Substring(0, 1)) + ",");
}
else
{
txtReport.AppendText(GetDescription(strPair.Substring(0, 1)));
}
}
}
}
return strTranslation;
}
That has no problem displaying in a text box, but when I try and put it as an item into a list box it turns it into null. Instead of:
"Trait 1 Het.,Trait 3 appears 16 times or 25%."
I get:
" appears 16 times or 25%."
I have tried adding the results to an ArrayList, then populating the listbox after everything is processed, but the result is the same.
Any clues as to why the list box is not accepting the translated AaBBCc information would be greatly appreciated.
strTranslation is never set. Everything is pushed to txtReport.AppendText

Categories

Resources