Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 11 months ago.
This post was edited and submitted for review 11 months ago and failed to reopen the post:
Original close reason(s) were not resolved
Improve this question
I have 2 Numeric strings with commas:
8,1,6,3,16,9,14,11,24,17,22,19
and
2,7,4,5,10,15,12,13,18,23,20,21
and I need to merge them Alternatively every Nth place
(for Example every 4th place to get)
8,1,2,7,6,3,4,5,16,9,10,15,14,11,12,13,24,17,18,23,22,19,20,21
I've already examined all recommended solutions but nothing worked for me.
Here's my current progress:
string result = "";
// For every index in the strings
for (int i = 0; i < JoinedWithComma1.Length || i < JoinedWithComma2.Length; i=i+2)
{
// First choose the ith character of the
// first string if it exists
if (i < JoinedWithComma1.Length)
result += JoinedWithComma1[i];
// Then choose the ith character of the
// second string if it exists
if (i < JoinedWithComma2.Length)
result += JoinedWithComma2[i];
}
Appreciate any assistance.
You can't rely on the length of the strings or select the "ith character" because not all "elements" (read: numbers) have the same number of characters. You should split the strings so you can get the elements out of the result arrays instead:
string JoinedWithComma1 = "8,1,6,3,16,9,14,11,24,17,22,19";
string JoinedWithComma2 = "2,7,4,5,10,15,12,13,18,23,20,21";
var split1 = JoinedWithComma1.Split(',');
var split2 = JoinedWithComma2.Split(',');
if (split1.Length != split2.Length)
{
// TODO: decide what you want to happen when the two strings
// have a different number of "elements".
throw new Exception("Oops!");
}
Then, you can easily write a for loop to merge the two lists:
var merged = new List<string>();
for (int i = 0; i < split1.Length; i += 2)
{
if (i + 1 < split1.Length)
{
merged.AddRange(new[] { split1[i], split1[i + 1],
split2[i], split2[i + 1] });
}
else
{
merged.AddRange(new[] { split1[i], split2[i] });
}
}
string result = string.Join(",", merged);
Console.WriteLine(
result); // 8,1,2,7,6,3,4,5,16,9,10,15,14,11,12,13,24,17,18,23,22,19,20,21
Try it online.
If you write a regular expression to get you a pair of numbers:
var r = new Regex(#"\d+,\d+");
You can break each string into a sequence of pairs:
var s1pairs = r.Matches(s1).Cast<Match>().Select(m => m.ToString());
var s2pairs = r.Matches(s2).Cast<Match>().Select(m => m.ToString());
And you can zip the sequences
var zipped = s1pairs.Zip(s2pairs,(a,b)=>a+","+b);
And join the bits together with commas
var result = string.Join(",", zipped);
How does it work?
The Regex matches any number of digits, followed by a comma, followed by any number of digits
In a string of
1,2,3,4,5,6
It matches 3 times:
1,2
3,4
5,6
Matches returns a MatchCollection containing all these matches. To be compatible with LINQ Select you need to Cast the MatchCollection to an IEnumerable<Match>. It is this way because MatchCollection predates the invention of IEnumerable<T> so it's enumerator returns objects that need casting. Once turned into an IEnumerable<Match> each match can be ToString'd by a Select, producing a sequence of strings that are pairs of numbers separated by comma. An s1pairs is effectively a collection of pairs of numbers:
new []{ "1,2", "3,4", "5,6" }
Repeat the same for string 2
Zip the sequences. As you might imagine from the name, Zip takes one from A then one from B then one from A then one from B, merging them like a zipper on clothing so two sequences of
new [] { "1,2", "3,4" }
new [] { "A,B", "C,D" }
When zipped end up as
new [] { "1,2,A,B", "3,4,C,D" }
And all that remains is to join it back together with a comma
"1,2,A,B,3,4,C,D"
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
When opening the console application, the user is supposed to paste in rows of dots and stars, all at once (It looks like a matrix). I want to make each of these rows into a seperate list. I think I know how to do it for column but can't get a hold on how I would go about it when it's about rows. Can someone help a new guy out?
Not so bad if you know a little LINQ
List<List<char>> lines = new List<List<char>>();
string line = string.Empty;
while((line = Console.ReadLine()) != null && line != string.Empty)
{
lines.Add(line.Select(x => x).Where(x => x != ' ').ToList());
}
We have a List of Lists of characters so that each "row" is represented as a "row" in this List>. Then we need to keep reading lines from the Console until it no longer returns a value. This is how we get every row the user has entered. So now we have a string line to process for each line read in this way. A little bit of LINQ allows us to go through each character x in the line, where the character x is not a space , and cast the result (all the non-whitespace characters) to a character list. Each time this is done we create a new row. Finally, we just add the row to the list of character rows we have, and voila. Hope this helps
I don't know exactly how your input is formatted, but you could use something like this to split on a space or a specific character in the .Split() method.
public List<string> SplitList = new List<string>();
public void SplitByRow()
{
var userInput = Console.ReadLine();
string[] splitArray = userInput != null ? userInput.Split(' ') : null;
SplitList = splitArray != null ? splitArray.ToList() : null;
}
public void Main(string res) {
var passedValues = res.Select(x => x).ToList();
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I have a file, that contains JSON string. Long string. Approx 700k symbols.
I'm trying to deserialize it.
But it contains symbols like \r and \n that should be replaces with comma ,.
I've tried to do it with Regex, but it stuck on it without error.
private static readonly Regex Pattern = new Regex("(\r\n|\r|\n)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Pattern.Replace(dataString, ",");
Also tried to convert string into StringBuilder and use simple .Replace
private readonly IDictionary<string, string> replacements = new Dictionary<string, string> { { "\r\n", "," }, { "\r", "," }, { "\n", "," } };
foreach (var replacement in this.replacements)
{
dataStringBuilder.Replace(replacement.Key, replacement.Value);
}
The second case was better but till the time when the file becomes larger.
So now I receive stuck for both cases.
Are there any other recommended faster solutions?
You could use a naïve approach of manually copying the string, converting line breaks yourself. This enables you to iterate the underlying character array only once, and avoids costly reallocations of string/StringBuilder objects:
char[] converted = new char[input.Length];
int pos = 0;
bool lastWasCr = false;
foreach(char c in input)
{
if(c == '\r')
{
converted[pos++] = ',';
lastWasCr = true;
}
else
{
if(c == '\n')
{
if(!lastWasCr)
converted[pos++] = ',';
}
else
converted[pos++] = c;
lastWasCr = false;
}
}
string output = new string(converted, 0, pos);
This loop iterates over every character, and detects and replaces line breaks. Note that we have to keep track of recent carriage returns (\r), to avoid double , on Windows line breaks (\r\n).
I compared your two approaches with the code above, using a random 650kb text file, and performing 1000 iterations of each implementation.
Results:
Regex.Replace: 62.3233sec (this does not even include initialization like compiling the regex)
StringBuilder.Replace: 7.0622sec (fixed version as indicated in a comment to your question)
Char-wise loop with if statement: 2.3862sec
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
The code is supposed to put all letters into lower case and change j to i, which it does. But I'm trying to take out any duplicate letters.
example inputted string = jjjaaaMMM expected output string = jam
what actually happens real output string = m please help I'm not sure what I'm missing.
string key = Secret.Text;
var keyLow = key.ToLower();
var newKey = keyLow.Replace("j", "i");
var set = new HashSet<char>(newKey);
foreach (char c in set)
{
Secret.Text = Char.ToString(c);
}
Your issue is entirely the = in
Secret.Text = Char.ToString(c);
it needs to be +=
Secret.Text += Char.ToString(c);
You were overwriting each value with the next.
However you could just use linq
Secret.Text = string.Concat(key.ToLower().Replace("j", "i").Distinct());
or probably more efficiently from #Ben Voigt comments
Since you have a sequence of char, it's probably more efficient to
call the string constructor than Concat
Secret.Text = new string(set.ToArray());
// or
Secret.Text = new string(key.ToLower()
.Replace("j", "i")
.Distinct()
.ToArray());
Additional Resources
String.Concat Method
Concatenates one or more instances of String, or the String
representations of the values of one or more instances of Object.
Enumerable.Distinct Method
Returns distinct elements from a sequence.
Others may answer the question directly. I'll provide an alternative. As always with string manipulation, there's a Regex for that.
var output = Regex.Replace(input, #"(.)\1*", "$1");
You can use Linq approach:
var text = key.ToLower().Distinct().ToArray();
Don't forgot add using System.Linq
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
Suppose I have a file with multiple line:
En;15;
Vu;
US;32;
I need to check if the string VU is contained so I did:
string text = #"En;15;
Vu;
US;32;"
var exist = text.Contains("Vu");
this will return true but I need to check also if the line of Vu contains only Vu or other contents as the other lines. How can I do this? Thanks.
UPDATE
if the line contains also other element should return false
Split your string into an array and that you will be able to separate all the lines into a separated indexes in the string array using the Split() method
with the separator '\n' that represents a new line:
static void Main(string[] args)
{
string stringfromfile = #"En;
15;
Vu;
US;
32;";
string[] ar = stringfromfile.Split('\n');
// remove ";" character and fix white space for safety
for (int i = 0; i < ar.Length; i++)
{
ar[i] = ar[i].Replace(";","").Trim();
}
if (ar.Contains("Vu"))
{
Console.WriteLine("TRUE");
}
else
{
Console.WriteLine("FALSE");
}
foreach (var itm in ar)
{
Console.WriteLine(itm);
}
Console.ReadLine();
}
Assuming that in your input a "newline" is "\n", and assuming that things in a line are separated by ";", then:
1) break the text into separate lines
2) for each line, break the line into pieces separated by ";"
3) for each broken-line, check each piece and see if Vu is there
4) ..and if it is, hey you found it
5) ..and if that broken-line had just 1 piece, hey, it was single Vu
Bits of code:
1)
#"text
that
has
lines".Split("\n") ==> array of 4 lines
2)
"linethat;has;pieces".Split(";") ===> array of 3 pieces
3) "for each" is a foreach loop. You will need one for lines, and one for pieces. One inside the other.
4) Split removes the separator, so ";" wont show up in a piece, so if(piece == "Vu")
5) "pieces" is array-of-strings, so if(pieces.Length==1) means that the line had a single piece
Now you have all bits, just use them properly.
You could try searching very simply for "\nVu\n" so it would look something little like:
var exist = text.Contains("\nVu\n");
This would find all cases except for the special cases of first and last line, and is more efficient than splitting the string into an array.
And as #quetzalcoatl said
..and first and last line can be covered by .StartsWith("Vu\n") and .EndsWith("\nVu")..