Displaying 5 strings from an array - c#

I want to display strings in a file that begins with the letter "F" (var target = "F";) and then print it in footlockerExistingBlogTextBox however only display 5 strings/lines. The file that holds the array contains more that 5 strings that begin with "F" and so I only want to display the last 5 latest entries. Thanks for your help in advance. Much appreciated.
Below displays my code:
var target = "F";
var results = footlockerArray.Where(r => r.StartsWith(target)).Reverse();
foreach (string result in results)
{
footlockerExistingBlogTextBox.Text += result;
}
for (int i = footlockerArray.Length - 1; i > footlockerArray.Length - 5; i--)
{
footlockerArray.Reverse();
footlockerExistingBlogTextBox.Text += footlockerArray[i];
}

Use Enumerable.Take and you can get the results like:
var results = footlockerArray.Where(r => r.StartsWith(target))
.OrderByDescending(r=> r)
.Take(5);
Then to get a string separated by a new line you can use string.Join like:
footlockerExistingBlogTextBox.Text = string.Join(Environment.NewLine, results);

Reverse and use Take(5):
footlockerArray
.Where(o => o.StartsWith("F"))
.Reverse()
.Take(5)
.Reverse()
.ToList()
.ForEach(o => footlockerExistingBlogTextBox.Text += o);

Related

Split and then Joining the String step by step - C# Linq

Here is my string:
www.stackoverflow.com/questions/ask/user/end
I split it with / into a list of separated words:myString.Split('/').ToList()
Output:
www.stackoverflow.com
questions
ask
user
end
and I need to rejoin the string to get a list like this:
www.stackoverflow.com
www.stackoverflow.com/questions
www.stackoverflow.com/questions/ask
www.stackoverflow.com/questions/ask/user
www.stackoverflow.com/questions/ask/user/end
I think about linq aggregate but it seems it is not suitable here. I want to do this all through linq
You can try iterating over it with foreach
var splitted = "www.stackoverflow.com/questions/ask/user/end".Split('/').ToList();
string full = "";
foreach (var part in splitted)
{
full=$"{full}/{part}"
Console.Write(full);
}
Or use linq:
var splitted = "www.stackoverflow.com/questions/ask/user/end".Split('/').ToList();
var list = splitted.Select((x, i) => string.Join("/", a.Take(i + 1)));
Linq with side effect:
string prior = null;
var result = "www.stackoverflow.com/questions/ask/user/end"
.Split('/')
.Select(item => prior == null
? prior = item
: prior += "/" + item)
.ToList();
Let's print it out
Console.WriteLine(string.Join(Environment.NewLine, result));
Outcome:
www.stackoverflow.com
www.stackoverflow.com/questions
www.stackoverflow.com/questions/ask
www.stackoverflow.com/questions/ask/user
www.stackoverflow.com/questions/ask/user/end
Linq without side effects ;)
Enumerable.Aggregate can be used here if we use List<T> as a result.
var raw = "www.stackoverflow.com/questions/ask/user/end";
var actual =
raw.Split('/')
.Aggregate(new List<string>(),
(list, word) =>
{
var combined = list.Any() ? $"{list.Last()}/{word}" : word;
list.Add(combined);
return list;
});
without Linq write below code,
var str = "www.stackoverflow.com/questions/ask/user/end";
string[] full = str.Split('/');
string Result = string.Empty;
for (int i = 0; i < full.Length; i++)
{
Console.WriteLine(full[i]);
}
for (int i = 0; i < full.Length; i++)
{
if (i == 0)
{
Result = full[i];
}
else
{
Result += "/" + full[i];
}
Console.WriteLine(Result);
}

Join List of strings trailing values don't require delimiters if the right most value is null

What im trying to achieve, but cant get my head around is if i have a list of strings say:
{"test","","data","","123","44"}
this should be joined by a character:
test::data::123:44
but if the list at the end is empty dont delimiter it
{"test","","data","","",""}
should be:
test::data
{"test","","","","",""}
should be:
test
{"test","","","","","44"}
should be:
test::::44
however the list can be of varying lengths which adds another level of complexity.
Just exclude the trailing empty elements from the list Count and then Join the remaining using Take:
List<string> input = ...;
int count = input.Count;
while (count > 0 && string.IsNullOrEmpty(input[count - 1]))
count--;
var output = string.Join(":", input.Take(count));
Using the List<T> specific FindLastIndex method, it can be reduced to the following "one liner":
var output = string.Join(":",
input.Take(input.FindLastIndex(s => !string.IsNullOrEmpty(s)) + 1));
First, with your array:
test = test.Where(x => !string.IsNullOrEmpty(x)).ToArray();
where "test" is your array.
then:
string.Join("::", test);
EDIT:
If you're getting your array of strings by splitting another string, consider the following:
string[] strs = myString.split(someDelimeter, StringSplitOptions.RemoveEmptyEntries);
Start by identifying the last element you want, then slice your list and join as you normally would:
var lastElementIndex = strings.Select((s, index) => string.IsNullOrEmpty(s) ? -1 : index).Max();
var prefix = strings.Take(lastElementIndex + 1);
var result = string.Join(":", prefix);
var obj = {"test","","data","","123","44"};
var count = obj.Count;
for (var i = count - 1; i > -1; i--)
{
if (obj[i]==String.Empty) {
obj.RemoveAt(i);
}
else break;
}
var arr = obj.Split(new char[] { ','}, StringSplitOptions.RemoveEmptyEntries);
var output = arr.Join(":", arr);

Find a fixed length string with specific string part in C#

I want to find a string of fixed length with specific substring. But I need to do it like we can do in SQL queries.
Example:
I have strings like -
AB012345
AB12345
AB123456
AB1234567
AB98765
AB987654
I want to select strings that have AB at first and 6 characters afterwards. Which can be done in SQL by SELECT * FROM [table_name] WHERE [column_name] LIKE 'AB______' (6 underscores after AB).
So the result will be:
AB012345
AB123456
AB987654
I need to know if there is any way to select strings in such way with C#, by using AB______.
You can use Regular Expressions to filter the result:
List<string> sList = new List<string>(){"AB012345",
"AB12345",
"AB123456",
"AB1234567",
"AB98765",
"AB987654"};
var qry = sList.Where(s=>Regex.Match(s, #"^AB\d{6}$").Success);
Considering you have an string array:
string[] str = new string[3]{"AB012345", "A12345", "AB98765"};
var result = str.Where(x => x.StartsWith("AB") && x.Length == 8).ToList();
The logic is if it starts with AB, and its length is 8. It is your best match.
this should do it
List<string> sList = new List<string>(){
"AB012345",
"AB12345",
"AB123456",
"AB1234567",
"AB98765",
"AB987654"};
List<string> sREsult = sList.Where(x => x.Length == 8 && x.StartsWith("AB")).ToList();
first x.Length == 8 determines the length and x.StartsWith("AB") determines the required characters at the start of the string
This can be achieved by using string.Startwith and string.Length function like this:
public bool CheckStringValid (String input)
{
if (input.StartWith ("AB") && input.Length == 8)
{
return true;
}
else
{
return false;
}
}
This will return true if string matches your criteria.
Hope this helps.
var strlist = new List<string>()
{
"AB012345",
"AB12345",
"AB123456",
"AB1234567",
"AB98765",
"AB987654"
};
var result = strlist.Where(
s => (s.StartsWith("AB") &&(s.Length == 8))
);
foreach(var v in result)
{
Console.WriteLine(v.ToString());
}

Linq: splitting a string length and storing the result using a list

I am new to Linq and am re-factoring some of my old code over to Linq. I have a small problem that I solved using the foreach loop that stores each 250 char's to a list. It would be good to rewrite this using linq, but it seems to not be working. Can someone shed a little light on this?
Code to be refactored:
string comment = "This can be however long but needs to be broken down into 250 chars and stored in a list";
char[] charList = comment.ToCharArray();
int charCount = charList.Count() / 250;
List<string> charCollection = new List<string>();
string tempStr = string.Empty;
foreach (char x in charList){
if (tempStr.Count() != 250){
tempStr = tempStr + x.ToString();
}
else {
if (tempStr.Count() <= 250) {
charCollection.Add(tempStr);
tempStr = "";
}
}
Not so good attempt with Linq:
IEnumerable<string> charCat = System.Linq.Enumerable.Where(comment, n => n.ToString().Length() => 250);
Using LINQ:
List<string> chunks =
comment
// for each character in the string, project a new item containing the
// character itself and its index in the string
.Select((ch, idx) => new { Character = ch, Index = idx })
// Group the characters by their "divisibility" by 250
.GroupBy(
item => item.Index / 250,
item => item.Character,
// Make the result of the GroupBy a string of the grouped characters
(idx, grp) => new string(grp.ToArray()))
.ToList();
See the documentation for .GroupBy and .Select for more information on those methods.
In general, I think the 101 LINQ samples on MSDN are a great resource for learning LINQ.

Cannot replace last element in string List

I have an input file that includes data on an entertainer and their performance score. For example,
1. Bill Monohan from North Town 10.54
2. Mary Greenberg from Ohio 3.87
3. Sean Hollen from Markell 7.22
I want to be able to take the last number from a line (their score), perform some math on it, and then replace the old score with the new score.
Here's a brief piece of code for what I'm trying to do:
string line;
StreamReader reader = new StreamReader(#"file.txt");
//Read each line and split by spaces into a List.
while ((line = reader.ReadLine())!= null){
//Find last item in List and convert to a Double in order to perform calculations.
List<string> l = new List<string>();
l = line.Split(null).ToList();
string lastItem = line.Split(null).Last();
Double newItem = Convert.ToDouble(lastItem);
/*Do some math*/
/*Replace lastItem with newItem*/
System.Console.WriteLine(line); }
When I write the new line, nothing changes but I want lastItem to be switched with newItem at the end of the line now. I've tried using:
l[l.Length - 1] = newItem.ToString();
But I'm getting no luck. I just need the best way to replace the last value of a string List like this. I've been going at this for a few hours now and I'm almost at the end of my rope.
Please help me c# masters!
You can use regular expression MatchEvaluator to get number from each line, do calculations, and replace original number with new one:
string line = "1. Bill Monohan from North Town 10.54";
line = Regex.Replace(line, #"(\d+\.?\d*)$", m => {
decimal value = Decimal.Parse(m.Groups[1].Value);
value = value * 2; // calculation
return value.ToString();
});
This regex captures decimal number at the end of input string. Output:
1. Bill Monohan from North Town 21.08
You're not changing anything to your line object before doing your WriteLine.
You will have to rebuild your line, something like this:
var items = string.Split();
items.Last() = "10";//Replace
var line = string.Join(" ", items)
Tip: strings are immutable, look it up.
This should work:
//var l = new List<string>(); // you don't need this
var l = line.Split(null).ToList();
var lastItem = l.Last(); // line.Split(null).Last(); don't split twice
var newItem = Convert.ToDouble(lastItem, CultureInfo.InvariantCulture);
/*Do some math*/
/*Replace lastItem with newItem*/
l[l.Count - 1] = newItem.ToString(); // change the last element
//Console.WriteLine(line); // line is the original string don't work
Console.WriteLine(string.Join(" ", l)); // create new string
This would probably do the job for you. A word on reading files though, if possible, ie they fit in memory, read the entire file at once, it gives you one disk access (well, depends on file size, but yeah) and you do not have to worry about filehandles.
// Read the stuff from the file, gets an string[]
var lines = File.ReadAllLines(#"file.txt");
foreach (var line in lines)
{
var splitLine = line.Split(' ');
var score = double.Parse(splitLine.Last(), CultureInfo.InvariantCulture);
// The math wizard is in town!
score = score + 3;
// Put it back
splitLine[splitLine.Count() - 1] = score.ToString();
// newLine is the new line, what should we do with it?
var newLine = string.Join(" ", splitLine);
// Lets print it cause we are out of ideas!
Console.WriteLine(newLine);
}
What do you want to do with the end result? Do you want it written back to file?
Try this
string subjectString = "Sean Hollen from Markell 7.22";
double Substring =double.Parse(subjectString.Substring(subjectString.IndexOf(Regex.Match(subjectString, #"\d+").Value), subjectString.Length - subjectString.IndexOf(Regex.Match(subjectString, #"\d+").Value)).ToString());
double NewVal = Substring * 10; // Or any of your operation
subjectString = subjectString.Replace(Substring.ToString(), NewVal.ToString());
Note: This will not work if the number appears twice on the same line
You are creating and initializing the list in a loop, hence it contains always only the current line. Do you want to find the highest score of all entertainers or the highest score of each entertainer (in case an entertainer could repeat in the file)?
However, here is an approach that gives you both:
var allWithScore = File.ReadAllLines(path)
.Select(l =>
{
var split = l.Split();
string entertainer = string.Join(" ", split.Skip(1).Take(split.Length - 2));
double score;
bool hasScore = double.TryParse(split.Last(), NumberStyles.Float, CultureInfo.InvariantCulture, out score);
return new { line = l, split, entertainer, hasScore, score };
})
.Where(x => x.hasScore);
// highest score of all:
double highestScore = allWithScore.Max(x => x.score);
// entertainer with highest score
var entertainerWithHighestScore = allWithScore
.OrderByDescending(x => x.score)
.GroupBy(x => x.entertainer)
.First();
foreach (var x in entertainerWithHighestScore)
Console.WriteLine("Entertainer:{0} Score:{1}", x.entertainer, x.score);
// all entertainer's highest scores:
var allEntertainersHighestScore = allWithScore
.GroupBy(x => x.entertainer)
.Select(g => g.OrderByDescending(x => x.score).First());
foreach (var x in allEntertainersHighestScore)
Console.WriteLine("Entertainer:{0} Score:{1}", x.entertainer, x.score);

Categories