I'm having trouble thinking of a logical way to achieve this. I have a method which sends a web request with a for loop that is counting up from 1 to x, the request counts up until it finds a specific response and then sends the URL + number to another method.
After this, saying we got the number 5, I need to create a string which displays as "1,2,3,4,5" but cannot seem to find a way to create the entire string, everything I try is simply replacing the string and only keeping the last number.
string unionMod = string.Empty;
for (int i = 1; i <= count; i++)
{
unionMod =+ count + ",";
}
I assumed I'd be able to simply add each value onto the end of the string but the output is just "5," with it being the last number. I have looked around but I can't seem to even think of what I would search in order to get the answer, I have a hard-coded solution but ideally, I'd like to not have a 30+ string with each possible value and just have it created when needed.
Any pointers?
P.S: Any coding examples are appreciated but I've probably just forgotten something obvious so any directions you can give are much appreciated, I should sleep but I'm on one of those all-night coding grinds.
Thank you!
First of all your problem is the +=. You should avoid concatenating strings because it allocates a new string. Instead you should use a StringBuilder.
Your Example: https://dotnetfiddle.net/Widget/qQIqWx
My Example: https://dotnetfiddle.net/Widget/sx7cxq
public static void Main()
{
var counter = 5;
var sb = new StringBuilder();
for(var i = 1; i <= counter; ++i) {
sb.Append(i);
if (i != counter) {
sb.Append(",");
}
}
Console.WriteLine(sb);
}
As it's been pointed out, you should use += instead of =+. The latter means "take count and append a comma to it", which is the incorrect result you experienced.
You could also simplify your code like this:
int count = 10;
string unionMod = String.Join(",", Enumerable.Range(1, count));
Enumerable.Range generates a sequence of integers between its two parameters and String.Join joins them up with the given separator character.
Related
I am working on an optimization pass for our asp.net web application and I want to shrink down and speed up as much of the backend as I can.
Is there any way to shrink down a for loop so that it becomes a lambda expression maybe?
A pure example of something that I might want to shrink down:
string outS = "";
for (int i = 0; i < length; i++)
{
outS += random.Next(0, 9).ToString();
}
return int.Parse(outS).ToString();
Instead of creating a new variable, performing some sort of function to generate it, and then returning it, is there a way where I can do all that in a single line? Like returning a lambda expression function?
Or is the current functionality the fastest way to do it anyway?
Like this silly example:
return => for(int i = 0; i < length; i++)
{
random.Next(0, 9).ToString();
}
If the logic method returns a random number that has a specified number of digits in the length variable, you could do something like this:
private int TestMethod(int length) =>
new Random().Next((int)Math.Pow(10, length - 1), (int)Math.Pow(10, length));
This form has some adventages:
No string concatenation. String concatenation is not recommended if many concatenations are performed.
The number of times a random number is requested is reduced (in the above code, the Random.Next method is only invoked once).
Nevertheless, it's a good practice that you perform a profiler comparing alternatives. You can do it with the Diagnostic Tools View in Visual Studio, and with the StopWatch class
If you're just wondering about condensing lines of code, you can use Linq's ForEach method and pass in a lambda expression.
This:
string outS = "";
for (int i = 0; i < length; i++)
{
outS += random.Next(0, 9).ToString();
}
return int.Parse(outS).ToString();
Becomes this:
string outS = "";
new List<int>(10).ForEach(_ => outS += random.Next(0, 9).ToString());
return int.Parse(outS).ToString();
I'm interested in doing something like this (C#):
int sum = 0;
for (int i = 0; i < 5; i++)
sum += i;
But I would like to do it on one line. Something like:
int sum = (embedded loop)
Is there any way to do this on one line? I'm looking to apply this to a more complex string manipulation algorithm so I can't simply replace the loop with an arithmatic formula.
So you want to loop and do something in one line?
First off, writing it in one line isn't going to make it run faster. You are still going to loop, you are still going to be O(n). For the particular problem you have in your question you can do something like:
var sum = Enumerable.Range(0,5).Sum();
This will basically make a collection of the numbers 0,1,2...4 and sum them.
More generally, since you want to do something, you might use the Aggregate function. For example:
var str = Enumerable.Range(0,5).Aggregate("",(p,c) => p + c); // Note: not efficient at all
Will take the values 0,1,...4 and do string concatenation with them (using a string builder would be better) to give you the string 01234.
Edit:
I'm trying to loop through a list of words and make each one title case, then return the string[].join(" ") of it
In that case, something like:
var result = string.Join(" ", myListOfWords.Select(w => char.ToUpper(w[0]) + w.Substring(1)));
Should work fine.
If you don't mind that 'sum' only is in scope of the for loop you could do this:
for (int i = 0, sum = 0; i < 5; sum += i, ++i) { // do something }
for(int i=0,sum = 0; i<5; sum+=i,++i){}
I;m using Lucene/.NET to implement a numerical search engine.
I want to filter numbers from within a large range, depends on which number exists in string array.
I used the following code:
int startValue = 1;
endValue = 100000;
//Assume that the following string array contains 12000 strings
String[] ArrayOfTerms = new String[] { "1", "10",................. , "99995"};
public String[] GetFilteredStrings(String[] ArrayOfTerms)
{
List<String> filteredStrings = new List<String>();
for (int i = startValue; i <= endValue; i++)
{
int index = Array.IndexOf(ArrayOfTerms,i.ToString());
if( index != -1)
{
filteredStrings.Add((String)ArrayOfTerms.GetValue(index));
}
}
return filteredStrings.ToArray();
}
Now, my problem is it searches every value from 1 to 100000 and takes too much time. some times my application is hanging.
Can anyone of you help me how to improve this performance issue? I don't know about caching concept, but I know that Lucene supports cache filters. Should I use a cache filter? Thanks in advance.
In fact you're trying to determine if an Array contains the item or not.
I think you should use something like a HashSet or Dictionary to be able to determine presence of the value for O(1) time instead of O(n) time you have.
This code works pretty much faster.
var results = ArrayOfTerms.Where(s => int.Parse(s) <= endValue);
If I got what you want to do
The program helps users to parse a text file by grouping certain part of the text files into "sections" array.
So the question is "Are there any methods to find out the line numbers/position within the array?" The program utilizes a foreach loop to read the "sections" array.
May someone please advise on the codes? Thanks!
namespace Testing
{
class Program
{
static void Main(string[] args)
{
TextReader tr = new StreamReader(#"C:\Test\new.txt");
String SplitBy = "----------------------------------------";
// Skip 5 lines of the original text file
for(var i = 0; i < 5; i++)
{
tr.ReadLine();
}
// Read the reststring
String fullLog = tr.ReadToEnd();
String[] sections = fullLog.Split(new string[] { SplitBy }, StringSplitOptions.None);
//String[] lines = sections.Skip(5).ToArray();
int t = 0;
// Tried using foreach (String r in sections.skip(4)) but skips sections instead of the Text lines found within each sections
foreach (String r in sections)
{
Console.WriteLine("The times are : " + t);
// Is there a way to know or get the "r" line number?
Console.WriteLine(r);
Console.WriteLine("============================================================");
t++;
}
}
}
}
A foreach loop doesn't have a loop counter of any kind. You can keep your own counter:
int number = 1;
foreach (var element in collection) {
// Do something with element and number,
number++;
}
or, perhaps easier, make use of LINQ's Enumerable.Select that gives you the current index:
var numberedElements = collection.Select((element, index) => new { element, index });
with numberedElements being a collection of anonymous type instances with properties element and index. In the case a file you can do this:
var numberedLines = File.ReadLines(filename)
.Select((Line,Number) => new { Line, Number });
with the advantage that the whole thing is processed lazily, so it will only read the parts of the file into memory that you actually use.
As far as I know, there is not a way to know which line number you are at within the file. You'd either have to keep track of the lines yourself, or read the file again until you get to that line and count along the way.
Edit:
So you're trying to get the line number of a string inside the array after the master string's been split by the SplitBy?
If there's a specific delimiter in that sub string, you could split it again - although, this might not give you what you're looking for, except...
You're essentially back at square one.
What you could do is try splitting the section string by newline characters. This should spit it out into an array that corresponds with line numbers inside the string.
Yes, you can use a for loop instead of foreach. Also, if you know the file isn't going to be too large, you can read all of the lines into an array with:
string[] lines = File.ReadAllLines(#"C:\Test\new.txt");
Well, don't use a foreach, use a for loop
for( int i = 0; i < sections.Length; ++ )
{
string section = sections[i];
int lineNum = i + 1;
}
You can of course maintain a counter when using a foreach loop as well, but there is no reason to since you have the standard for loop at your disposal which is made for this sort of thing.
Of course, this won't necessarily give you the line number of the string in the text file unless you split on Environment.NewLine. You are splitting on a large number of '-' characters and I have no idea how your file is structured. You'll likely end up underestimating the line number because all of the '---' bits will be discarded.
Not as your code is written. You must track the line number for yourself. Problematic areas of your code:
You skip 5 lines at the beginning of your code, you must track this.
Using the Split method, you are potentially "removing" lines from the original collection of lines. You must find away to know how many splits you have made, because they are an original part of the line count.
Rather than taking the approach you have, I suggest doing the parsing and searching within a classic indexed for-loop that visits each line of the file. This probably means giving up conveniences like Split, and rather looking for markers in the file manually with e.g. IndexOf.
I've got a much simpler solution to the questions after reading through all the answers yesterday.
As the string had a newline after each line, it is possible to split the strings and convert it into a new array which then is possible to find out the line number according to the array position.
The Codes:
foreach (String r in sections)
{
Console.WriteLine("The times are : " + t);
IList<String> names = r.Split('\n').ToList<String>();
}
I am fairly new to C# programming and I am stuck on my little ASP.NET project.
My website currently examines Twitter statuses for URLs and then adds those URLs to an array, all via a regular expression pattern matching procedure. Clearly more than one person will update a with a specific URL so I do not want to list duplicates, and I want to count the number of times a particular URL is mentioned in, say, 100 tweets.
Now I have a List<String> which I can sort so that all duplicate URLs are next to each other. I was under the impression that I could compare list[i] with list[i+1] and if they match, for a counter to be added to (count++), and if they don't match, then for the URL and the count value to be added to a new array, assuming that this is the end of the duplicates.
This would remove duplicates and give me a count of the number of occurrences for each URL. At the moment, what I have is not working, and I do not know why (like I say, I am not very experienced with it all).
With the code below, assume that a JSON feed has been searched for using a keyword into srchResponse.results. The results with URLs in them get added to sList, a string List type, which contains only the URLs, not the message as a whole.
I want to put one of each URL (no duplicates), a count integer (to string) for the number of occurrences of a URL, and the username, message, and user image URL all into my jagged array called 'urls[100][]'. I have made the array 100 rows long to make sure everything can fit but generally, this is too big. Each 'row' will have 5 elements in them.
The debugger gets stuck on the line: if (sList[i] == sList[i + 1]) which is the crux of my idea, so clearly the logic is not working. Any suggestions or anything will be seriously appreciated!
Here is sample code:
var sList = new ArrayList();
string[][] urls = new string[100][];
int ctr = 0;
int j = 1;
foreach (Result res in srchResponse.results)
{
string content = res.text;
string pattern = #"((https?|ftp|gopher|telnet|file|notes|ms-help):((//)|(\\\\))+[\w\d:##%/;$()~_?\+-=\\\.&]*)";
MatchCollection matches = Regex.Matches(content, pattern);
foreach (Match match in matches)
{
GroupCollection groups = match.Groups;
sList.Add(groups[0].Value.ToString());
}
}
sList.Sort();
foreach (Result res in srchResponse.results)
{
for (int i = 0; i < 100; i++)
{
if (sList[i] == sList[i + 1])
{
j++;
}
else
{
urls[ctr][0] = sList[i].ToString();
urls[ctr][1] = j.ToString();
urls[ctr][2] = res.text;
urls[ctr][3] = res.from_user;
urls[ctr][4] = res.profile_image_url;
ctr++;
j = 1;
}
}
}
The code then goes on to add each result into a StringBuilder method with the HTML.
Is now edite
The description of your algorithm seems fine. I don't know what's wrong with the implementation; I haven't read it that carefully. (The fact that you are using an ArrayList is an immediate red flag; why aren't you using a more strongly typed generic collection?)
However, I have a suggestion. This is exactly the sort of problem that LINQ was intended to solve. Instead of writing all that error-prone code yourself, just describe the transformation you're interested in, and let the compiler work it out for you.
Suppose you have a list of strings and you wish to determine the number of occurrences of each:
var notes = new []{ "Do", "Fa", "La", "So", "Mi", "Do", "Re" };
var counts = from note in notes
group note by note into g
select new { Note = g.Key, Count = g.Count() }
foreach(var count in counts)
Console.WriteLine("Note {0} occurs {1} times.", count.Note, count.Count);
Which I hope you agree is much easier to read than all that array logic you wrote. And of course, now you have your sequence of unique items; you have a sequence of counts, and each count contains a unique Note.
I'd recommend using a more sophisticated data structure than an array. A Set will guarantee that you have no duplicates.
Looks like C# collections doesn't include a Set, but there are 3rd party implementations available, like this one.
Your loop fails because when i == 99, (i + 1) == 100 which is outside the bounds of your array.
But as other have pointed out, .Net 3.5 has ways of doing what you want more elegantly.
If you don't need to know how many duplicates a specific entry has you could do the following:
LINQ Extension Methods
.Count()
.Distinct()
.Count()