What's wrong with this ForEach loop? - c#

Yep... it's one of those days.
public string TagsInput { get; set; }
//further down
var tagList = TagsInput.Split(Resources.GlobalResources.TagSeparator.ToCharArray()).ToList();
tagList.ForEach(tag => tag.Trim()); //trim each list item for spaces
tagList.ForEach(tag => tag.Replace(" ", "_")); //replace remaining inner word spacings with _
Both ForEach loops don't work. tagList is just a List.
Thank you!

Trim() and Replace() don't modify the string they're called on. They create a new string that has had the action applied to it.
You want to use Select, not ForEach.
tagList = tagList.Select(t => t.Trim()).Select(t => t.Replace(" ", "_")).ToList();

ForEach (and other "linq" methods) does not modify the list instance.
tagList = tagList.Select(tag => tag.Trim().Replace(" ", "_")).ToList();

The reason is string is immutuable. So the result of each Trim() or Replac() function will produce a new string. You need to reassign to the original element in order to see the updated value.

This is exactly why Microsoft havent implemented ForEach on an IEnumerable. What's wrong with this?
public string[] TagsInput { get; set; }
//further down
var adjustedTags = new List<string>();
foreach (var tag in TagsInput.Split(Resources.GlobalResources.TagSeparator.ToCharArray()))
{
adjustedTags.Add(tag.Trim().Replace(" ", "_"));
}
TagsInput = adjustedTags.ToArray();

If by don't work, you mean that they don't actually do anything, I think you need to adjust your code a bit:
public string TagsInput { get; set; }
//further down
var tagList = TagsInput.Split(Resources.GlobalResources.TagSeparator.ToCharArray()).ToList();
tagList.ForEach(tag => tag = tag.Trim()); //trim each list item for spaces
tagList.ForEach(tag => tag = tag.Replace(" ", "_")); //replace remaining inner word spacings with _
Trim and Replace don't change the value of the string, they return the new string value.

Related

Problems with List<string> when adding strings by variable

I wanna do a list without duplicates from a file which have too many lines with identifier, sometimes repeated. When I try using List<string>.Contains, it doesn't work. This is, I think, because I'm adding object instead of strings directly.
public List<string> obterRelacaoDeBlocos()
{
List<string> listaDeBlocos = new List<string>();
foreach(string linhas in arquivos.obterLinhasDoArquivo())
{
string[] linhaQuebrada = linhas.Split('|');
string bloco = linhaQuebrada[1].ToString();
if (listaDeBlocos.Contains((string)bloco) != true)
{
listaDeBlocos.Add( bloco + ":" + listaDeBlocos.Contains(bloco).ToString());
}
}
return listaDeBlocos;
}
You're appending ":" + listaDeBlocos.Contains(bloco).ToString() to the string before you add it to the list. That's not going to match when you encounter the same word again, so Contains will return false and the same word will get added again.
I don't see what point it serves to append ": true" to the end of each string in the list anyway, so just remove that part and it should work.
if (!listaDeBlocos.Contains(bloco))
{
listaDeBlocos.Add(bloco);
}
Since you're only interested in one part of each string, based on how you're splitting, you could rewrite your method using LINQ. This is untested but should work:
public List<string> obterRelacaoDeBlocos()
{
return arquivos.obterLinhasDoArquivo().Select(x => x.Split('|')[1]).Distinct().ToList();
}

How to remove a specific string from list<strings>

I've got a list of strings called xyz the string has this structure iii//abcd, iii//efg. how can I loop through this list and remove only iii// ?
I have tried this but it remove everything. thanks
string mystring = "iii//";
xyz.RemoveAll(x=> x.Split ('//')[0].ToString().Equals (mystring));
Removing all the strings who start with iii//:
xyz.RemoveAll(x => x.StartsWith(#"iii//"));
Removing the iii// from all strings:
var newList = xyz.Select(x => x.Replace(#"iii//", string.Empty)).ToList();
You can try this also which will remove the string from list if it starts with "iii/" other wise not.
string mystring = "iii//";
xyz.RemoveAll(x=>x.StartsWith(mystring));
I believe OP wants something to remove iii// from all strings:
string prefix = "iii///";
List<string> xyz = ...;
var result = xyz.Select(x => x.Substring(prefix.Length)).ToList();
Note: this of course assumes that each string really starts with prefix.

How to create a readable List<string> output?

My code is as follows:
public List<string> connect(String query_physician, String query_institution)
{
Regex pattern = new Regex(#"(?<=""link""\:\s"")[^""]*(?="")");
MatchCollection linkMatches = pattern.Matches(customSearchResult);
var list = new List<string>();
list = linkMatches.Cast<Match>().Select(match => match.Value).ToList(); //put the links into a list?!
foreach (var item in list) //take each item (link) out of the list...
{
return item; // ...and return it?! //Error, because item is a string
}
return null;
}
Like you see, I want to return each link (as a readable list of my json result and display it in my RichTextBox, but I know, var item is a string. Otherwise it doesn´t work. Either I become an unreadable list, or a string (with string.Join(.....Cast<>()).
Do I have this right, string.Join(.....Cast<>()) adds the single strings together? Still, I don't want them together. Anyway, do you know a way to solve this problem?
By the way, return null is only a wildcard.
As I understand it is continuation of your previous question. Assuming you have this function (I simplified it a bit):
public List<string> connect(String query_physician, String query_institution)
{
...
return Regex.Matches(customSearchResult, #"(?<=""link""\:\s"")[^""]*(?="")")
.Cast<Match>()
.Select(m => m.Value)
.ToList();
}
You can do the following:
List<string> list = connect("", "");
string linksFormatted = string.Join(",", list);
To show the content in RichTextBox:
richTextBox1.AppendText(string.Join(Environment.NewLine, list));
Look at your method signature return type is List of string no string,
so much simplest approach:
public List<string> connect(String query_physician, String query_institution)
{ ...
//restults container
List<string> resultContainer = new List<String>();
Regex pattern = new Regex(#"(?<=""link""\:\s"")[^""]*(?="")");
MatchCollection linkMatches = pattern.Matches(customSearchResult);
var list = new List<string>();
list = linkMatches.Cast<Match>().Select(match => match.Value).ToList(); //put the links into a list?!
foreach (var item in list) //take each item (link) out of the list...
{
//add item to list
resultContainer.Add(item);
}
return resultContainer;
}

Method to check array list containing specific string

I have an ArrayList that import records from a database.
Is there any method to check whether the arrayList contains schname that i want to match to another list which is an api?
List<PrimaryClass> primaryList = new List<PrimaryClass>(e.Result);
PrimaryClass sc = new PrimaryClass();
foreach (string item in str)
{
for (int a = 0; a <= e.Result.Count - 1; a++)
{
string schname = e.Result.ElementAt(a).PrimarySchool;
string tophonour = e.Result.ElementAt(a).TopHonour;
string cca = e.Result.ElementAt(a).Cca;
string topstudent = e.Result.ElementAt(a).TopStudent;
string topaggregate = e.Result.ElementAt(a).TopAggregate;
string topimage = e.Result.ElementAt(a).TopImage;
if (item.Contains(schname))
{
}
}
}
This is what I have come up with so far, kindly correct any errors that I might have committed. Thanks.
How about ArrayList.Contains?
Try this
foreach( string row in arrayList){
if(row.contains(searchString)){
//put your code here.
}
}
Okay, now you've shown that it's actually a List<T>, it should be easy with LINQ:
if (primaryList.Any(x => item.Contains(x.PrimarySchool))
Note that you should really consider using foreach instead of a for loop to iterate over a list, unless you definitely need the index... and if you're dealing with a list, using the indexer is simpler than calling ElementAt.
// check all types
var containsAnyMatch = arrayList.Cast<object>().Any(arg => arg.ToString() == searchText);
// check strings only
var containsStringMatch = arrayList.OfType<string>().Any(arg => arg == searchText);

get values from string

in my variable:
string selectedObjects;
i have one long value like:
"123;132;213;231;"
i want to get 4 times values as: "123;" , "132;" , "213;" and "231;".
i tryed with foreach as:
public ActionResult ShowHistory(string selectedObjects)
{
foreach (string item in selectedObjects)
{
item = selectedObjects.Split(';');
}
but it doesnt work. how can i do that?
The flow is incorrect. Split returnes an array through which you should than iterate, using foreach if that's your choice. So:
foreach (string item in selectedObjects.Split(';'))
{
// do whatever you want with the items
}
You can use a regular expression:
foreach (Match m in Regex.Matches("123;132;213;231;", #"\d+;"))
string value = m.Value; //Do something worthwhile with the value.
All of the other answers are wrong or overkill - unless I'm missing something.
public ActionResult ShowHistory(string selectedObjects)
{
foreach (string tempItem in selectedObjects.Split(new []{';'}, StringSplitOptions.RemoveEmptyEntries))
{
string item = tempItem + ";"; // Add back on the ; character
}
// .. do something
The RemoveEmptyEntries is required, otherwise, you'll get an empty string at the end (because your input string ends with ";"). Also, string.Split does not preserve the separator char, so you need to add it back in if you want it (hence the tempItem).
Split returns an array of string.
string selectedObjects = ...;
foreach (string item in selectedObjects.Split(';'))
{
// do work
}
foreach(string item in selectedObjects.Split(new [] {';'},
StringSplitOptions.RemoveEmptyEntries)
.Select( x=> x+";"))
{
//process item
}
Split method returns array of string, try somehting like this
string selectedObjects = "123;132;213;231;";
string[] s = selectedObjects.Split(';');
foreach (string item in s )
{
Console.Writeline(item.ToString());
}
You need to append the semi-colon again after splitting.
public ActionResult ShowHistory(string selectedObjects)
{
var items = selectedObjects.Split(';')
.Where(i => !string.IsNullOrEmpty(i))
.Select(i => i + ";");
...
}
Or (if you can guarantee that exact format)
public ActionResult ShowHistory(string selectedObjects)
{
var items = selectedObjects.TrimEnd(';')
.Split(';')
.Select(i => i + ";");
...
}

Categories