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
Related
I need to reverse a string using a for loop but I just can't do it. What I'm doing wrong?
class Program
{
static void Main(string[] args)
{
string s;
string sReverse;
Console.WriteLine("Say any word please: ");
s = Console.ReadLine();
for (int i = 0; i < s.Length; i++)
{
s[s.Length - i] = sReversa[i];
}
}
}
Strings are immutable. You can't change them character by character.
If you want random access to the characters in a string, convert it to a char array first (using ToCharArray), then convert it back when you're done (String has a constructor that accepts a char array).
string a = "1234";
char[] b = a.ToCharArray();
b[1] = 'X';
a = new string(b);
Console.WriteLine("{0}", a);
Output:
1X34
There are much easier ways to reverse a string (e.g. LINQ would let you do var output = new string(input.Reverse().ToArray());), but if you want to use a for loop and your current approach, this is probably the piece of information you are missing.
These will be the minimal changes required in your code:
public static void Main()
{
string s;
string sReverse = string.Empty; // Initialise (always recommended)
Console.WriteLine("Say any word please: ");
s = Console.ReadLine();
for (int i = s.Length-1; i >=0 ; i--) // Chnage the order of indexing
{
sReverse += s[i]; // makes a new string everytime since strings are immutable.
}
Console.WriteLine(sReverse); // print your new string
}
As others said this may not be the best approach for very large number of string manipulation / formation. Instead, use StringBuilder.
StringBuilder is suited in situations where you need to perform repeated modifications to a string, the overhead associated with
creating a new String object can be costly.
Below is the snippet on how to use StringBuilder:
using System;
using System.Text; // Add this for StringBuilder
public class Program
{
public static void Main()
{
string s;
StringBuilder sReverse = new StringBuilder(); // Instantiate the object.
Console.WriteLine("Say any word please: ");
s = Console.ReadLine();
for (int i = s.Length-1; i >=0 ; i--)
{
sReverse.Append(s[i]); // Keep Appending to original string.
}
Console.WriteLine(sReverse.ToString()); // finally convert to printable string.
}
}
string reverse = string.Join("", "some word".Reverse());
You can not use s[s.Length - i] = sReversa[i];
Because Strings are immutable.
Instead, you can use sReverse = sReverse + s[Length];
The following code will give you reverse of a string:
static void Main(string[] args)
{
string s;
string sReverse = "";
int Length;
Console.WriteLine("Say any word please: ");
s = Console.ReadLine();
Length = s.Length - 1;
for (int i = Length; i >= 0; i--)
{
sReverse = sReverse + s[Length];
Length--;
}
Console.WriteLine("{0}", sReverse);
Console.ReadLine();
}
Note: For a large number of iteration, this might be a performance issue.
The simplest way to make your code work with minimal changes is to use a StringBuilder. Unlike string a StringBuilder is mutable.
Here's the code:
Console.WriteLine("Say any word please: ");
string s = Console.ReadLine();
StringBuilder sb = new StringBuilder(s);
for (int i = 0; i < s.Length; i++)
{
sb[s.Length - i - 1] = s[i];
}
string r = sb.ToString();
If you must use a for loop the way you want, you will have to allocate a new char array, initialize it with the string's characters from back to front, then take advantage of the string constructor that takes a char array as input. The code looks as follows:
public static string ReverseWithFor(string s)
{
if (string.IsNullOrEmpty(s)) return s;
char[] a = new char[s.Length];
for (int i = 0; i < s.Length; i++)
a[s.Length - 1 - i] = s[i];
return new string(a);
}
I am doing this in this way but its remove string previous characters, its out put is (Magic,Agic,Gic,Ic,C) but I want the whole string to be concate before and after.
public string[] Transform(string st)
{
string[] arr = new string[st.Length];
string[] arr1 = new string[st.Length];
for (int x = 0; x < st.Length; x++)
{
arr1[x] = char.ToLower(st[x]) + "".ToString();
}
for (int i = 0; i < st.Length; i++)
{
string st1 = "";
{
st1 = char.ToUpper(st[i]) + st.Substring(i + 1);
}
arr[i] = st1;
}
return arr;
}
You can do this with a single loop:
public static string[] Transform(string str)
{
var strs = new List<string>();
var sb = new StringBuilder();
for (int i = 0; i < str.Length; i++)
{
sb.Clear();
sb.Append(str);
sb[i] = char.ToUpper(str[i]);
strs.Add(sb.ToString());
}
return strs.ToArray();
}
What this does is adds the str to a StringBuilder and then modifies the indexed character with the upper case version of that character. For example, the input abcde will give:
Abcde
aBcde
abCde
abcDe
abcdE
Try it out on DotNetFiddle
If you wanted to get really fancy I'm sure there is some convoluted LINQ that can do the same, but this gives you a basic framework for how it can work.
You forgot to add left part of the string. Try to do like this:
st1 = st.ToLower().Substring + char.ToUpper(st[i]) + st.Substring(i + 1);
Here. This is twice as fast as the method that uses a string builder and a List
public static string[] Transform(string str)
{
var strs = new string [str.Length];
var sb = str.ToCharArray();
char oldCh;
for (int i = 0; i < str.Length; i++)
{
oldCh = sb[i];
sb[i] = char.ToUpper(sb[i]);
strs[i] = new string (sb);
sb[i] = oldCh;
}
return strs;
}
There's no need to clear and keep reading the string to the string builder. We also know the size of the array so that can be allocated at the start.
I wrote an answer for your questions (it's second code snippet), you can modify it for your needs, like changing the return type to string[], or use ToArray() extension method if you wanna stick with it. I think it's more readable this way.
I decided to put a the end little profiler to check CPU usage and memory compared to #Ron Beyer answer.
Here is my first attempt:
public static void Main()
{
var result = Transform("abcde");
result.ToList().ForEach(WriteLine);
}
public static IEnumerable<string> Transform(string str)
{
foreach (var w in str)
{
var split = str.Split(w);
yield return split[0] + char.ToUpper(w) + split[1];
}
}
Result:
Abcde
aBcde
abCde
abcDe
abcdE
Code fiddle https://dotnetfiddle.net/gnsAGX
There is one huge drawback of that code above, it works only if the passed word has unique letters. Therefore "aaaaa" won't produce proper result.
Here is my second successful attempt that seems works with any string input. I used one instance of StringBuilder to decrease the number of objects that would need to be created and manage on one instance, instead of so much copying objects so it's more optimized.
public static void Main()
{
var result = Transform("aaaaa");
result.ToList().ForEach(WriteLine);
}
public static IEnumerable<string> Transform(string str)
{
var result = new StringBuilder(str.ToLower());
for( int i = 0; i < str.Length; i++)
{
result[i] = char.ToUpper(str[i]);
yield return result.ToString();
result[i] = char.ToLower(str[i]);
}
}
Result:
Aaaaa
aAaaa
aaAaa
aaaAa
aaaaA
Code fiddle: https://dotnetfiddle.net/tzhXtP
Measuring execute time and memory uses.
I will use dotnetfiddle.net status panel, to make it easier.
Fiddle has few limitations like time execution of code 10 sec and used memory
besides differences are very significant.
I tested programs with 14 000 repetitions, my code additionally changes the output to array[].
My answer (https://dotnetfiddle.net/1fLVw9)
Last Run: 12:23:09 pm
Compile: 0.046s
Execute: 7.563s
Memory: 16.22Gb
CPU: 7.609s
Compared answer (https://dotnetfiddle.net/Zc88F2)
Compile: 0.031s
Execute: 9.953s
Memory: 16.22Gb
CPU: 9.938s
It slightly reduces the execution time.
Hope this helps!
public static string[] Transform(string str)
{
var strs = new string [str.Length];
var sb = str.ToCharArray();
char oldCh;
for (int i = 0; i < str.Length; i++)
{
oldCh = sb[i];
sb[i] = char.ToUpper(sb[i]);
strs[i] = new string (sb);
sb[i] = oldCh;
}
return strs;
}
I'm facing a problem while developing an application.
Basically,
I have a fixed string, let's say "IHaveADream"
I now want to user to insert another string, for my purpose of a fixed length, and then concatenate every character of the fixed string with every character of the string inserted by the user.
e.g.
The user inserts "ByeBye"
then the output would be:
"IBHyaevBeyAeDream".
How to accomplish this?
I have tried with String.Concat and String.Join, inside a for statement, with no luck.
One memory-efficient option is to use a string builder, since both the original string and the user input could potentially be rather large. As mentioned by Kris, you can initialize your StringBuilder capacity to the combined length of both strings.
void Main()
{
var start = "IHaveADream";
var input = "ByeBye";
var sb = new StringBuilder(start.Length + input.Length);
for (int i = 0; i < start.Length; i++)
{
sb.Append(start[i]);
if (input.Length >= i + 1)
sb.Append(input[i]);
}
sb.ToString().Dump();
}
This only safely accounts for the input string being shorter or equal in length to the starting string. If you had a longer input string, you'd want to take the longer length as the end point for your for loop iteration and check that each array index is not out of bounds.
void Main()
{
var start = "IHaveADream";
var input = "ByeByeByeByeBye";
var sb = new StringBuilder(start.Length + input.Length);
var length = start.Length >= input.Length ? start.Length : input.Length;
for (int i = 0; i < length; i++)
{
if (start.Length >= i + 1)
sb.Append(start[i]);
if (input.Length >= i + 1)
sb.Append(input[i]);
}
sb.ToString().Dump();
}
You can create an array of characters and then re-combine them in the order you want.
char[] chars1 = "IHaveADream".ToCharArray();
char[] chars2 = "ByeBye".ToCharArray();
// you can create a custom algorithm to handle
// different size strings.
char[] c = new char[17];
c[0] = chars1[0];
c[1] = chars2[0];
...
c[13] = chars1[10];
string s = new string(c);
var firstString = "Ihaveadream";
var secondString = "ByeBye";
var stringBuilder = new StringBuilder();
for (int i = 0; i< firstString.Length; i++) {
stringBuilder .Append(str[i]);
if (i < secondString.Length) {
stringBuilder .Append(secondStr[i]);
}
}
var result = stringBuilder.ToString();
If you don't care much about memory usage or perfomance you can just use:
public static string concatStrings(string value, string value2)
{
string result = "";
int i = 0;
for (i = 0; i < Math.Max(value.Length, value2.Length) ; i++)
{
if (i < value.Length) result += value[i].ToString();
if (i < value2.Length) result += value2[i].ToString();
}
return result;
}
Usage:
string conststr = "IHaveADream";
string input = "ByeBye";
var result = ConcatStrings(conststr, input);
Console.WriteLine(result);
Output: IBHyaevBeyAeDream
P.S.
Just checked perfomance of both methods (with strBuilder and simple cancatenation) and it appears to be that both of this methods take same time to execute (if you have just one operation). The main reason for it is that string builder take considerable time to initialize while with use of concatenation we don't need that.
But in case if you have to process something like 1500 strings then it's different story and string builder is more of an option.
For 100 000 method executions it showed 85 (str buld) vs 22 (concat) ms respectively.
My Code
How can I delete the first n lines in a string?
Example:
String str = #"a
b
c
d
e";
String output = DeleteLines(str, 2)
//Output is "c
//d
//e"
You can use LINQ:
String str = #"a
b
c
d
e";
int n = 2;
string[] lines = str
.Split(Environment.NewLine.ToCharArray())
.Skip(n)
.ToArray();
string output = string.Join(Environment.NewLine, lines);
// Output is
// "c
// d
// e"
If you need to take into account "\r\n" and "\r" and "\n" it's better to use the following regex:
public static class StringExtensions
{
public static string RemoveFirstLines(string text, int linesCount)
{
var lines = Regex.Split(text, "\r\n|\r|\n").Skip(linesCount);
return string.Join(Environment.NewLine, lines.ToArray());
}
}
Here are some more details about splitting text into lines.
Combination of Get the index of the nth occurrence of a string? (search for Environment.NewLine) and substring should do the trick.
Try the following:
public static string DeleteLines(string s, int linesToRemove)
{
return s.Split(Environment.NewLine.ToCharArray(),
linesToRemove + 1
).Skip(linesToRemove)
.FirstOrDefault();
}
the next example:
string str = #"a
b
c
d
e";
string output = DeleteLines(str, 2);
returns
c
d
e
Try this:
public static string DeleteLines (string text, int lineCount) {
while (text.Split('\n').Length > lineCount)
text = text.Remove(0, text.Split('\n')[0].Length + 1);
return text;
}
It might not be very efficient but it works perfectly for the little project i've been working on recently
Try the following:
private static string DeleteLines(string input, int lines)
{
var result = input;
for(var i = 0; i < lines; i++)
{
var idx = result.IndexOf('\n');
if (idx < 0)
{
// do what you want when there are less than the required lines
return string.Empty;
}
result = result.Substring(idx+1);
}
return result;
}
Note: This method is not ideal for extremely long multi-line strings as it does not consider memory management. If dealing with these kind of strings, I suggest you alter the method to use the StringBuilder class.
With ability to delete first n lines or last n lines:
public static string DeleteLines(
string stringToRemoveLinesFrom,
int numberOfLinesToRemove,
bool startFromBottom = false) {
string toReturn = "";
string[] allLines = stringToRemoveLinesFrom.Split(
separator: Environment.NewLine.ToCharArray(),
options: StringSplitOptions.RemoveEmptyEntries);
if (startFromBottom)
toReturn = String.Join(Environment.NewLine, allLines.Take(allLines.Length - numberOfLinesToRemove));
else
toReturn = String.Join(Environment.NewLine, allLines.Skip(numberOfLinesToRemove));
return toReturn;
}
public static string DeleteLines(string input, int linesToSkip)
{
int startIndex = 0;
for (int i = 0; i < linesToSkip; ++i)
startIndex = input.IndexOf('\n', startIndex) + 1;
return input.Substring(startIndex);
}
I want to split a string in C#.NET that looks like this:
string Letters = "hello";
and put each letter (h, e, l, l, o) into an array or ArrayList. I have no idea what to use as the delimiter in String.Split(delimiter). I can do it if the original string has commas (or anything else):
string Letters = "H,e,l,l,o";
string[] AllLettersArray = Letters.Split(",".ToCharArray());
But I have no idea what to use in a case with (supposedly) no delimiter. Is there a special character like Environment.Newline? Thanks.
Remember, you can access a string as an array in c#.
string str = "hello";
char[] letters = str.ToCharArray();
Here is another full solution that uses a loop. This takes a regular string "helloworld" and puts each character into an array as a string. The most straightforward method without using LINQ or other references.
string str = "helloworld";
string[] arr = new string[str.Length];
for(int i=0; i<str.Length; i++)
{
arr[i] = str[i].ToString();
}
This can be added to your codebase as an extension method.
public static class StringExtensions
{
public static string[] ToStringArray(this string str)
{
string[] arr = new string[str.Length];
for(int i=0; i<str.Length; i++)
{
arr[i] = str[i].ToString();
}
return arr;
}
}
And then you have a 1 liner for the conversion.
string str = "helloworld";
string[] arr = str.ToStringArray();