Convert string list to string when only item present - c#

I have a function that returns a list of strings:
string displayText;
List<string> list = new List<string>();
list = GetListOfStrings();
if(list.Count > 1)
{
displayText = string.Join("\r", list.ToArray());
}
else
{
displayText = list.ToString();
}
If there are several string in the List then I separate them by \r for display purposes, if there is only one then I cant to convert it to string.
But the above shows "System.Collections.Generic.List1[System.String]" when there is only one string.
What is the best way to do this when there is only one string in the list?

No reason to use ToString on the list -- just grab the first (and only) item:
displayText = list[0];
Both answers in the comments seem correct as well, though ToString on a string is a bit redundant. I think "remove the if" is actually the best answer.

Use SingleOrDefault() for getting the only item in the list
if(list.Count > 1)
{
displayText = string.Join("\r", list.ToArray());
}
else
{
displayText = list.SingleOrDefault();
}

Not having more than one item doesn't mean it has one item.
You can use:
string displayText;
List<string> list = new List<string>();
list = GetListOfStrings();
displayText = string.Join("\r", list);

Related

How to search through combobox with a string containing a wildcat?

I have a combo-box that contains lots of entries like this small extract
1R09ST75057
1R11ST75070
1R15ST75086
1R23ST75090
2R05HS75063
2R05ST75063
3R05ST75086
2R07HS75086
The user now enters some information in the form that result in a string being produced that has a wildcat (unknown) character in it at the second character position
3?05ST75086
I now want to take this string and search\filter through the combo-box list and be left with this item as selected or a small set of strings.
If I know the string without the wildcat I can use the following to select it in the Combo-box.
cmbobx_axrs75.SelectedIndex = cmbobx_axrs75.Items.IndexOf("2R05HS75063");
I thought I could first create a small subset that all have the first char the same then make a substring of each minus the first two chars and check this but I can have a large amount of entries and this will take too much time there must be an easier way?
Any ideas how I can do this with the wildcat in the string please?
Added info:
I want to end up with the selected item in the Combobox matching my string.
I choose from items on the form and result in string 3?05ST75086. I now want to take this and search to find which one it is and select it. So from list below
1R05ST75086
2R05ST75086
3R05ST75086
6R05ST75086
3R05GT75086
3R05ST75186
I would end up with selected item in Combo-box as
3R05ST75086
You could use regular expressions. Something like this:
string[] data = new string[]
{
"1R09ST75057",
"1R11ST75070",
"1R15ST75086",
"1R23ST75090",
"2R05HS75063",
"2R05ST75063",
"3R05ST75086",
"2R07HS75086"
};
string pattern = "3*05ST75086";
string[] results = data
.Where(x => System.Text.RegularExpressions.Regex.IsMatch(x, pattern))
.ToArray();
You can use a regular expression for this task. First, you need a method to convert your pattern string to Regex like this (it should handle "*" and "?" wildcards):
private static string ConvertWildCardToRegex(string value)
{
return "^" + Regex.Escape(value).Replace("\\?", ".").Replace("\\*", ".*") + "$";
}
Then you will use it like the following:
List<string> comboBoxValues = new List<string>()
{
"1R09ST75057",
"1R11ST75070",
"1R15ST75086",
"1R23ST75090",
"2R05HS75063",
"2R05ST75063",
"3R05ST75086",
"2R07HS75086"
};
string searchPattern = "3?05ST75086";
string patternAsRegex = ConvertWildCardToRegex(searchPattern);
var selected = comboBoxValues.FirstOrDefault(c => Regex.IsMatch(c, patternAsRegex));
if (selected != null)
{
int selectedIndex = comboBoxValues.IndexOf(selected);
}
This assumes you only care about first found match. If you need all matches then substitute FirstOrDefault(...) with Where(...) clause and swap "if" statement with a foreach loop.
Thanks to all that helped I used a combination of items from all answers so everyone helped me answer this.
I added this function from the answers as it seems a good idea, thanks
private static string ConvertWildCardToRegex(string value)
{
return "^" + Regex.Escape(value).Replace("\\?", ".").Replace("\\*", ".*") + "$";
}
Then I get the combo box items into a list. I search the list and make some more decisions based on the result of the search.
List<string> comboBoxValues = new List<string>();
for (int i = 0; i < cmbobx_in_focus.Items.Count; i++)
{
comboBoxValues.Add(cmbobx_in_focus.GetItemText(cmbobx_in_focus.Items[i]));
}
string[] results = comboBoxValues
.Where(x => Regex.IsMatch(x, ConvertWildCardToRegex(lbl_raster_used.Text)))
.ToArray();
I now have array called results which is easy to work with.

Compare results of 2 split strings?

I have two string inputs with that have been split so each item is distinguishable from the other (these items are product properties such as length, weight, finish, stain color, etc.). One string has the original values for the product while the other has the new values (whatever they may be--users can edit whichever product values they want).
Right now, I have the split strings producing the info that I want but I am not sure how to compare the results to each other since the individual product values are inside foreach loops.
This is what I have:
//checks to see which attributes have been changed/edited for the product
protected bool ifAttrChanged(string oldItm, string newItm)
{
bool retVal = false;
//get the original attributes of the product
string[] oldItms = oldItm.Split(',');
foreach (string oItm in oldItms)
{
if (oItm != "")
{
string[] oldThings = oItm.Split(',');
string oldies = oldThings.GetValue(0).ToString();
}
}
//get whatever new values have been entered for the product
string[] newItms = newItm.Split(',');
foreach (string nItm in newItms)
{
if (nItm != "")
{
string[] newThings = nItm.Split(',');
string newbies = newThings.GetValue(0).ToString();
}
}
if (newItms.ToString().Equals(oldItms.ToString(), StringComparison.Ordinal))
{
retVal = false;
Label3.Text += retVal.ToString() + "<br />";
}
else
{
retVal = true;
Label3.Text += retVal.ToString() + "<br />";
}
return retVal;
}
I would really like to compare the oldies string variable with the newbies string variable (weird names but I am not concerned about that) but they are each in their own foreach statement and I cannot access them elsewhere. How can I compare the old and new values of the two split strings successfully so I can obtain which values were changed and which values remained the same?
With all the strings splittend and stored in arrays (oldItems and newItems), and using System.Linq.
Try this:
var changedResults = newItems.Where(x => !oldItems.Any(y => x == y));
With this you will get a IEnumerable with all the string in newItems which no appear in oldItems array.
If you want to convert this to a list or something, add this:
var changedResults = newItems.Where(x => !oldItems.Any(y => x == y)).ToList();
I hope this helps
What is a "change"? Addition? Deletion? Modification?
If only addition, Oscar's method works. This is the same thing (set difference) but a little more concise:
var changedResults = newItems.Except(oldItems)
However, if a deletion is a "change" as well, you would need to consider it from both sides.
var changedResults = newItems.Except(oldItems).Union(oldItems.Except(newItems));
Since the sets are of only strings, there is no notion of modification.

Removing an element from list if it contains particular text in it

I have a C# method in which I look for certain text say username in a list with element in the format username + datetime and if any part of text matches the element in the list, then the entire element has to be removed from the list
Method to add to the c# List
string active_user = model.UserName.ToString();
string datetime = "(" + DateTime.Now + ")";
List<string> activeUsers = new List<string>();
if (activeUsers.Any(str => str.Contains(active_user)))
{
//do nothing
}
else
{
activeUsers.Add(active_user+datetime);
}
Now I would like a method that deletes the element if it matches the username or any part of element something like
if (activeUsers.Contains(active_user))
{
activeUsers.Remove(active_user);
}
While the other answers are correct, you should note that they will delete any matches. For example, active_user = "John" will remove "John", "John123", "OtherJohn", etc.
You can use regular expressions to test, or if user names don't have parentheses, do your test like this:
string comp = active_user + "("; // The ( is the start of the date part
activeUsers.RemoveAll(u => u.StartsWith(comp));
Also note, this is case sensitive.
You can do something like
activeUsers.RemoveAll(u => u.Contains(active_user));
That will match and remove all elements of activeUser that contain the text in active_user.
var user = activeUsers.FirstOrDefault(au => au.Contains(active_user);
if(user != null)
activeUsers.Remove(user);
if you are only wanting to remove the first match, else :
var users = activeUsers.Where(au => au.Contains(active_user);
foreach(var user in users)
activeUsers.Remove(user);
Or more simply, the RemoveAll method Eric answered with.
If i Want to remove Numeric String Values List Items from my List
List<ModelName> ModelList = new List<ModelName>();
var regex = new Regex(#"\d");
foreach(var item in ModelList.ToList())
{
if (regex.IsMatch(item.PropertyName))
{
ModelList.RemoveAll(t => t.PropertyName== item.PropertyName);//Or
ModelList.RemoveAll(t => t.PropertyName.Contains(item.PropertyName));//Or You Can Use Contains Method
}
}
return ModelList;
This will remove all items from list those having Numeric values as a string and return only Character String in List items

Variable string editing

I have a form on which you can select multiple items to create a code.
Eg. if I clicked on "name", it would add that to the string, then if I clicked "age" it would then add that to the string, but if I unchecked "name", it would remove it from the string.
I have no idea of how to go about this. Can someone help?
Take a List<string> and add/remove items to/from the list. Once you are done, you make a call to string.Join and construct a single string from array.
List<string> items = new List<string>(); // declare globally
private void add(string item)
{
items.Add(item);
}
private void remove(string item)
{
items.Remove(item);
}
private string convertArrayToString(string delimiter, List<string> elements)
{
delimiter = (delimiter == null) ? "" : delimiter;
return string.Join(delimiter, elements.ToArray());
}
Note:
Giving a priority to List<T> over string[] would be a good decision since, here collection would be resize. Have a look at this discussion which can help you on this.
Simply use a List.
List<string> myList = new List<string>();
myList.Add("Somestring");
Then you can use the following methods:
myList.Remove or myList.RemoveAll or myList.RemoveAt and so on.
Why not using List? it allows you to add/remove elements easily?
if you click on name, just add it to the list, when you uncheck the name, remove it from the list,
after that, you can convert your list into a string and use it.
//Add string
var myList = new List<string>();
//After clicking:
myList.add(clickedElement);
//After uncheck
myList.remove(uncheckedElement);
//At the end, just convert your list to string to use it
var myString = string.Join(" ", myList.ToArray());

how can modify or add new item into generic list of strings

i want to remove some pretty words in list of words.
public System.String CleanNoiseWord(System.String word)
{
string key = word;
if (word.Length <= 2)
key = System.String.Empty;
else
key = word;
//other validation here
return key;
}
public IList<System.String> Clean(IList<System.String> words)
{
var oldWords = words;
IList<System.String> newWords = new string[oldWords.Count()];
string key;
var i = 0;
foreach (System.String word in oldWords)
{
key = this.CleanNoiseWord(word);
if (!string.IsNullOrEmpty(key))
{
newWords.RemoveAt(i);
newWords.Insert(i++, key);
}
}
return newWords.Distinct().ToList();
}
but i can't add, remove or insert any thing in list! and exception NotSupportedException occured >> Collection was of a fixed size. how i can modify or add new item into generic list of strings?
Of course LINQ could make it nice and easy:
return words.Where(p => !string.IsNullOrEmpty(CleanNoiseWord(p))
.Distinct()
.ToList();
Of course we could take this one step further and inline the function call to CleanNoiseWord and drastically simplify your Clean method:
public IList<System.String> Clean(IList<System.String> words)
{
return words.Where(p => !string.IsNullOrEmpty(p) && p.Length > 2)
.Distinct()
.ToList();
}
If no words meet the criteria in the predicate then an empty list will be returned. If you are passing a very large list and want to lazy evaluate it (MSDN) then remove the ToList() from the end - this way actual evaluation of the list will not be performed until you convert it to an actual list. (To be fair, here's a blog post about some of the gotchas of lazy (deferred) evaluation).
I suggest that you create a method
bool IsNoiseWord(string word)
and do this:
words.RemoveAll(IsNoiseWord);
edit: this will only work for actual lists, otherwise
return words.Where(x=>!IsNoiseWord(x)).Distinct().ToList()
As already said, array is a fixed size list. Use the List instead.
IList<string> newWords = new List<string>(oldWords);
Your code is wrong. Instead of
IList<System.String> newWords = new string[oldWords.Count()];
Make this
IList<System.String> newWords = new List<String>();
You do not need to initialize to a certain size with a generic list.
You cannot insert items into a fixed size list, a happy medium would be to create a new list and insert as you "clean".
Following Mike's answer,
public bool IsNoise(String word)
{
return (word.Length <= 2) && validation2 && validation3;
}
public List<String> Clean(List<String> words)
{
words.RemoveAll(IsNoise);
return words;
}

Categories