This is an extension of the question asked here:
Converting string to int and then back to string
I am now converting a range of string values to add all of them together. I obviously cannot do something like:
int Total;
string str1 = "1";
string str2 = "1";
string str3 = "1";
string str4 = "1";
string str5 = "1";
string str6 = "1";
...
...
void Start()
{
Total = int.Parse(str1) + int.Parse(str2) + .....
}
I am looking for a way to parse all the strings into int such that:
Total = int.Parse(str1 + str2 + str3 + ...)
How do I achieve this?
As long as you do not know how many values you will have, you cannot hardcode all the single values into independent variables.
Advice: You should really consider storing the data in the correct format, You approach should be working with integers instead of strings (using a List<int>). The code would be more bug resistant and more simple.
int Total = 0;
List<string> valuesToAdd = new List<string>(){
"1",
"4",
"1",
"99"
};
void Start()
{
Total = 0;
foreach(string stringValue in valuesToAdd)
{
Total += int.Parse(stringValue);
}
}
Related
The code I tried:
public void ConcatIntegers() {
string s = "";
for (int i = 0; i <= 5; i++) {
s += i.ToString();
}
Console.WriteLine($ "{s}");
Console.Read();
}
In Above method + is used to concatenate multiple values but I was looking for anyway except join, aggregate, concatenate function, instead of + symbol I want to use string interpolation ($) directly which store concatenated string into a string variable.
string s = "";
for (int i = 0; i <= 5; i++) {
// Some code which use string interpolation to
// concatenat multiple string and that result is stored in s
// variable.
}
Console.WriteLine($ "{s}");
Console.Read();
except join, aggregate, concatenate function, instead of + symbol I want to use string interpolation ($)
directly which store concatenated string into a string variable...
simply try:
string result = string.Empty;
for (var i = 0; i <= 5; i++) result = $"{result}{i}";
Use StringBuilder since if you do that a lot it is much faster
Use AppendFormat
StringBuilder sb = new StringBuilder();
string var1 = "abcd";
string var2 = "efgh";
sb.AppendFormat("example: {0}, {1}", var1, var2);
I would use String Builder to concatenate the string:
Your code after changes:
StringBuilder sb = new StringBuilder();
string s = "";
sb.Append(s);
for (int i = 0; i <= 5; i++)
{
sb.Append(i);
}
Console.WriteLine(sb);
Console.ReadLine();
If you want to concatenate, let's try string.Concat or string.Join; with a little help of Linq (in order to get rid of for loop) we'll get
using System.Linq;
...
// static: we don't use "this" in the method
public static void ConcatIntegers() {
// Concatenate range of 0..5 integers: "012345"
Console.WriteLine(string.Concat(Enumerable
.Range(0, 6))); // 6 - we want 6 numbers: 0..5
Console.Read();
}
In case you want to use some format, string interpolation etc. add Select:
public static void ConcatIntegers() {
// "000102030405" since we apply "d2" format (each number reprsented with 2 digits)
Console.WriteLine(string.Concat(Enumerable
.Range(0, 6)
.Select(i => $"{i:d2}"))); // each item in 2 digits format
Console.Read();
}
I had a similar issue on using string interpolation in string.join
string type1 = "a,b,c";
string[] type2 = new string[3] { "a", "b", "c" };
string result = string.Join(",", $"'{x}'");
In both cases, the output should be 'a','b','c'
how to use string.Join() with string interpolation for array of strings
I have over 27,000,000 string variable in the array. When I add a string to another one speed is greatly reduced. my code is:
//public string[] part2 = { .....
string Str1;
string Str0;
Parallel.ForEach(index_choose, x =>
{
Str1 += part1[x];
Str0 += part2[x];
//progressBar1.PerformStep();
//label1.Text = progressBar1.Value.ToString();
//Application.DoEvents();
});
string total = Str1 + Str0;
Run this code on a powerful CPU takes More than 20 hours!
I will recommend to use StringBuilder - like in the following example
StringBuilder str0 = new StringBuilder();
StringBuilder str1 = new StringBuilder();
Parallel.ForEach(index_choose, x =>
{
Str1.Append(part1[x]);
Str0.Append(part2[x]);
//progressBar1.PerformStep();
//label1.Text = progressBar1.Value.ToString();
//Application.DoEvents();
});
string total = Str1.Append(Str0).ToString();
For example, I have two string variables:
string a = " Hello ";
string b = " World ";
How can I swap it without a temporary variable?
I found an example, but it used a third variable for the length of a:
int len1 = a.Length;
a = a + b;
b = a.Substring(0, len1);
a = a.Substring(len1);
How can I do that?
UPD, suggested solution for decimal data type, in ma case i've asked about string data type.
You can use SubString without using a temp variable, like this:
string a = " Hello ";
string b = " World ";
a = a + b;//" Hello World "
b = a.Substring(0, (a.Length - b.Length));//" Hello "
a = a.Substring(b.Length);//" World "
Just use some other means of swapping.
string stringOne = "one";
string stringTwo = "two";
stringOne = stringOne + stringTwo;
stringTwo = stringOne.Substring(0, (stringOne.Length - stringTwo.Length));
stringOne = stringOne.Substring(stringTwo.Length);
// Prints stringOne: two stringTwo: one
Console.WriteLine("stringOne: {0} stringTwo: {1}", stringOne, stringTwo);
string str1 = "First";
string str2 = "Second";
str1 = (str2 = str1 + str2).Substring(str1.Length);
str2 = str2.Substring(0,str1.Length-1);
I'm fond of doing it this way although underneath it's using resources to make it fully thread-safe, and I wouldn't be surprised if it was using a local variable behind the scenes.
string str1 = "First";
string str2 = "Second";
str2 = System.Interlocked.Exchange(ref str1, str2);
I am making a game, and I am trying to make my game moddable, so I am making that the game reads a list of possible buildings and their stats line by line, from a text file, and then splits the values accordingly. Everything seems to be working fine, I am even using a pretty similar piece of code in another part of the game and it works just fine, but when I try to use it here, it gives me this exception.
public static void parseBuildings()
{
Building[] parsedBuildings = new Building[500];
string[] buildingList = System.IO.File.ReadAllLines(AppDomain.CurrentDomain.BaseDirectory + #"\data\buildings.turd");
int i = 0;
foreach (string line in buildingList)
{
string[] parts = line.Split(',');
//MessageBox.Show(parts[0] + parts[1] + parts[2] + parts[3] + parts[4] + parts[5]);
//File format - name,description,unused(price),baseprice,count(unused),hps
parsedBuildings[i].name = parts[0];
parsedBuildings[i].description = parts[1];
//parsedBuildings[i].price = int.Parse(parts[2]);
parsedBuildings[i].baseprice = int.Parse(parts[3]);
//parsedBuildings[i].count = int.Parse(parts[4]);
parsedBuildings[i].hps = int.Parse(parts[5]);
i++;
}
Array.Resize(ref parsedBuildings, buildingList.Length);
buildings = parsedBuildings;
}
This here makes the game fill the array 'buildings' from a temporary array called 'parsedBuildings'
The funny thing is that the NullReferenceException happens at the parsedBuildings[i].description = parts[1]; line, and the commented message box works just fine.
This is how the 'buildings' array is instantiated.
public static Building[] buildings = {new Building("Loading", "Loading", 1,1,0,0)};
And this is what the Building class looks like
public class Building
{
public string name;
public string description;
public int price;
public int baseprice;
public int count;
public int hps;
public Building(string nam, string desc, int pri, int bpri, int cnt, int hp)
{
name = nam;
description = desc;
price = pri;
baseprice = bpri;
count = cnt;
hps = hp;
}
}
Please help me get this solution working, because it is miles better than what I previously used.
It is not enough just to create the array
Building[] parsedBuildings = new Building[500];
You should also initialize it. For instance:
for(int k = 0; k < parsedBuildings.Length; k++)
parsedBuildings[k] = new Building();
I have a string with a number at the end, after a dash ("-"). I'd like to create that same string with that number incremented by 1. Pretty simple, but I'm wondering if there's a better approach to this? Thanks!
string oldString = "BA-0001-3";
int lastIndex = oldString.LastIndexOf("-");
string oldNumber = oldString.SubString(lastIndex + 1);
string oldPartialString = oldString.SubString(0, lastIndex);
int newNumber = Convert.ToInt32(oldNumber) + 1;
string newString = oldPartialString + newNumber.ToString();
Regex?
Example:
Regex.Replace("BA-0001-3", #"[A-Z]{2}-\d{4}-(\d+)",
m => (Convert.ToInt32(m.Groups[1].Value) + 1).ToString())
I would probably use my friend string.Split:
string oldString = "BA-0001-3";
string[] parts = oldString.Split('-');
parts[parts.Length-1] = (Convert.ToInt32(parts[parts.Length-1])+1).ToString();
string newString = string.Join("-", parts);
A small tweak that will perhaps make it quicker (by accessing parts.Length and subtracting 1 only once - didn't profile so it's purely a guess, and it is likely a marginal difference anyway), but above all more robust (by using int.TryParse):
string oldString = "BA-0001-3";
string[] parts = oldString.Split('-');
int number;
int lastIndex = parts.Length-1;
parts[lastIndex] = (int.TryParse(parts[lastIndex], out number) ? ++number : 1).ToString();
string newString = string.Join("-", parts);
Updated per Ahmad Mageed's comments below. This is his answer much more than it is mine now :-)
I would do it the way you have it now, but for fun wanted to see if I could do it with linq.
var x = "BA-0001-3".Split('-');
var y = x.First() + "-" + x.ElementAt(1) + "-" + (Convert.ToInt32(x.Last()) + 1);
This works in LINQPad.
Edit: Obviously I'm not a pro with linq. Hopefully there will be other answers/comments on how this can be improved.
Here's an example of how it could be done with RegEx:
public void Test()
{
System.Text.RegularExpressions.Regex rx = new Regex(#"(?<prefix>.*\-)(?<digit>\d+)");
string input = "BA-0001-3";
string output = string.Empty;
int digit = 0;
if (int.TryParse(rx.Replace(input, "${digit}"), out digit))
{
output = rx.Replace(input, "${prefix}" + (digit + 1));
}
Console.WriteLine(output);
}
Using the regex (which already seems to have now been filled in with more details) I end up with something like:
var regex = new Regex(#"^(?<Category>[A-Za-z]{1,2})-(?<Code>[0-9]{4})-(?<Number>[0-9]+)$");
var newCode = regex.Replace("BA-0001-3", new MatchEvaluator(ReplaceWithIncrementedNumber));
Where the MatchEvaluator function is:
public static string ReplaceWithIncrementedNumber(Match match)
{
Debug.Assert(match.Success);
var number = Int32.Parse(match.Groups["Number"].Value);
return String.Format("{0}-{1}-{2}", match.Groups["Category"].Value, match.Groups["Code"].Value, number + 1);
}
Here is an example of a class that exposes the three parts of your "part number". Not particularly fancy (also note the absence of error checking/validation).
class Program
{
static void Main(string[] args)
{
PartNumber p1 = new PartNumber("BA-0001-3");
for (int i = 0; i < 5; i++)
{
p1.Sub++;
Debug.WriteLine(p1);
}
PartNumber p2 = new PartNumber("BA", 2, 3);
for (int i = 0; i < 5; i++)
{
p2.Sub++;
Debug.WriteLine(p2);
}
}
}
class PartNumber
{
public PartNumber(string make, int model, int sub)
{
Make = make;
Model = model;
Sub = sub;
}
public PartNumber(string part)
{
//Might want to validate the string here
string [] fields = part.Split('-');
//Are there 3 fields? Are second and third fields valid ints?
Make = fields[0];
Model = Int32.Parse(fields[1]);
Sub = Int32.Parse(fields[2]);
}
public string Make { get; set; }
public int Model { get; set; }
public int Sub { get; set; }
public override string ToString()
{
return string.Format("{0}-{1:D4}-{2}", Make, Model, Sub);
}
}