LINQ to List<> to String - Best Optimized Method - c#

I have a string List<string> this would apply to all Lists. I needed to get the first item in a string list and then convert what I got back to a string.
Here is the working code using linq:
public List<string> AppGroup = new List<string>();
var group = SearchParameters.AppGroup.Take(1);
string firstAppGroup = String.Join(",", group.ToArray());
My question would be; Is this the best method to do what I am going for? Is there a better or shorter way to write this out? A good example of considering performance would be appreciated. If what I have is fine and no changes are needed, please let me know.
I am using framework 3.5 and above.

Your current means of grabbing the first item in the list is somewhat long-winded, and stems from the fact that using Take(1) returns an IEnumerable rather than the item in question.
Assuming SearchParameters.AppGroup is List<string>
string firstAppGroup =
SearchParameters.AppGroup.FirstOrDefault(); //returns null on empty set
is a much briefer way of stating the same intent.
EDIT:
As #CodeInChaos states, if you don't want to deal with a null value, use the null-coalescing operator to substitute an empty string in the case that null is returned:
string firstAppGroup =
SearchParameters.AppGroup.FirstOrDefault() ?? string.Empty;

Could be a one liner:
string firstAppGroup = String.Join(",", SearchParameters.AppGroup.First());

Related

Check All Elements for String

I want to check if my array class has the string "Unavailable" contained for all elements:
classApplicantNDatesCount[] applicantCounts = null;
....
...
applicantCounts = appCount.ToArray();
Specifically this "part" of the array I need to search through:
applicantCounts[i].NadraDateAvailableforApplicant = "All Requested Slots UnAvailable"
So I need to check if all of applicantCounts[i].NadraDateAvailableforApplicant elements contains the string "Unavailable".
I have looked into Array.TrueforAll but not found a way to apply it to my situtation.
Apologies I don't think Im using the correct terminology which might make this slightly unclear.....
LINQ eats this sort of thing for breakfast:
applicantCounts.All(a => a.NadraDateAvailableforApplicant.Contains("Unavailable"))
We're using .All here to check if a condition is true for all elements of an enumerable.
Note you have a capitalization typo in the string search.
Using Array.TrueForAll would look like this:
bool all = Array.TrueForAll(
applicantCounts,
x => x.NadraDateAvailableforApplicant.Contains("Unavailable")
);
As for #Benjamin's approach, i would use IndexOf instead of Contains where you can specify a StringComparison in case you'd like a case insensitive search and or specify CultureInfo:
applicantCounts.All(app => app.NadraDateAvailableforApplicant.IndexOf("Unavailable", StringComparison.OrdinalIgnoreCase) >= 0);

Check if Characters in ArrayList C# exist - C# (2.0)

I was wondering if there is a way in an ArrayList that I can search to see if the record contains a certain characters, If so then grab the whole entire sentence and put in into a string. For Example:
list[0] = "C:\Test3\One_Title_Here.pdf";
list[1] = "D:\Two_Here.pdf";
list[2] = "C:\Test\Hmmm_Joke.pdf";
list[3] = "C:\Test2\Testing.pdf";
Looking for: "Hmmm_Joke.pdf"
Want to get: "C:\Test\Hmmm_Joke.pdf" and put it in the Remove()
protected void RemoveOther(ArrayList list, string Field)
{
string removeStr;
-- Put code in here to search for part of a string which is Field --
-- Grab that string here and put it into a new variable --
list.Contains();
list.Remove(removeStr);
}
Hope this makes sense. Thanks.
Loop through each string in the array list and if the string does not contain the search term then add it to new list, like this:
string searchString = "Hmmm_Joke.pdf";
ArrayList newList = new ArrayList();
foreach(string item in list)
{
if(!item.ToLower().Contains(searchString.ToLower()))
{
newList.Add(item);
}
}
Now you can work with the new list that has excluded any matches of the search string value.
Note: Made string be lowercase for comparison to avoid casing issues.
In order to remove a value from your ArrayList you'll need to loop through the values and check each one to see if it contains the desired value. Keep track of that index, or indexes if there are many.
Then after you have found all of the values you wish to remove, you can call ArrayList.RemoveAt to remove the values you want. If you are removing multiple values, start with the largest index and then process the smaller indexes, otherwise, the indexes will be off if you remove the smallest first.
This will do the job without raising an InvalidOperationException:
string searchString = "Hmmm_Joke.pdf";
foreach (string item in list.ToArray())
{
if (item.IndexOf(searchString, StringComparison.OrdinalIgnoreCase) >= 0)
{
list.Remove(item);
}
}
I also made it case insensitive.
Good luck with your task.
I would rather use LINQ to solve this. Since IEnumerables are immutable, we should first get what we want removed and then, remove it.
var toDelete = Array.FindAll(list.ToArray(), s =>
s.ToString().IndexOf("Hmmm_Joke.pdf", StringComparison.OrdinalIgnoreCase) >= 0
).ToList();
toDelete.ForEach(item => list.Remove(item));
Of course, use a variable where is hardcoded.
I would also recommend read this question: Case insensitive 'Contains(string)'
It discuss the proper way to work with characters, since convert to Upper case/Lower case since it costs a lot of performance and may result in unexpected behaviours when dealing with file names like: 文書.pdf

String insertion problem in c#

I am trying to insert a string at a position for C# string, its failing
here is the snippet.
if(strCellContent.Contains("<"))
{
int pos = strCellContent.IndexOf("<");
strCellContent.Insert(pos,"<");
}
please tell me the solution
The return value contains the new string that you desire.
strCellContent = strCellContent.Insert(pos,"<");
Gunner and Rhapsody have given correct changes, but it's worth knowing why your original attempt failed. The String type is immutable - once you've got a string, you can't change its contents. All the methods which look like they're changing it actually just return a new value. So for example, if you have:
string x = "foo";
string y = x.Replace("o", "e");
the string x refers to will still contain the characters "foo"... but the string y refers to will contain the characters "fee".
This affects all uses of strings, not just the particular situation you're looking at now (which would definitely be better handled using Replace, or even better still a library call which knows how to do all the escaping you need).
I think you might be better of with a Replace instead of an Insert:
strCellContent = strCellContent.Replace("<", "<");
Maybe doing Server.HtmlEncode() is even better:
strCellContent = Server.HtmlEncode(strCellContent);
When I look at your code I think you want to do a replace, but try this:
if(strCellContent.Contains("<"))
{
int pos = strCellContent.IndexOf("<");
strCellContent = strCellContent.Insert(pos,"<");
}
.Contains is not a good idea here, because you need to know the position. This solution will be more efficient.
int pos = strCellContent.IndexOf("<");
if (pos >= 0) //that means the string Contains("<")
{
strCellContent = strCellContent.Insert(pos,"<"); //string is immutable
}
As others have explained with the code, I will add that
The value of the String object is the
content of the sequential collection,
and that value is immutable (that is,
it is read-only).
For more information about the immutability of strings, see the Immutability and the StringBuilder Class section.
from: http://msdn.microsoft.com/en-us/library/system.string.aspx

C# Array contains partial

How to find whether a string array contains some part of string?
I have array like this
String[] stringArray = new [] { "abc#gmail.com", "cde#yahoo.com", "#gmail.com" };
string str = "coure06#gmail.com"
if (stringArray.Any(x => x.Contains(str)))
{
//this if condition is never true
}
i want to run this if block when str contains a string thats completely or part of any of array's Item.
Assuming you've got LINQ available:
bool partialMatch = stringArray.Any(x => str.Contains(x));
Even without LINQ it's easy:
bool partialMatch = Array.Exists(stringArray, x => str.Contains(x));
or using C# 2:
bool partialMatch = Array.Exists(stringArray,
delegate(string x) { return str.Contains(x)); });
If you're using C# 1 then you probably have to do it the hard way :)
If you're looking for if a particular string in your array contains just "#gmail.com" instead of "abc#gmail.com" you have a couple of options.
On the input side, there are a variety of questions here on SO which will point you in the direction you need to go to validate that your input is a valid email address.
If you can only check on the back end, I'd do something like:
emailStr = "#gmail.com";
if(str.Contains(emailStr) && str.length == emailStr.length)
{
//your processing here
}
You can also use Regex matching, but I'm not nearly familiar enough with that to tell you what pattern you'd need.
If you're looking for just anything containing "#gmail.com", Jon's answer is your best bets.

When to use FOR-CASE (Foreach/switch in C#)?

I've found what seems to be the C# equivalent of a FOR-CASE structure in a project I'm working on:
foreach (string param in params.Split(';'))
{
string[] parts = param.Split('=');
string key = parts[0].Trim().ToLower();
string value = parts[1].Trim();
switch (key)
{
case "param1": this.param1 = value; break;
case "param2": this.param2 = value; break;
case "param3": this.param3 = value; break;
case "param4": this.param4 = value; break;
default: break;
}
}
(Variable names changed to protect the guilty.)
How would you implement this code?
I don't think the code in your question is anything like the code you linked to....
The code in the question looks like something I might do if I wrote a command line tool.
Am I stupid for not seeing whats wrong with the code in the question?
An alternative is to use reflection to fill parameter value variables. I've done it that ways sometimes too.
BTW: I once wrote a program in a script language that had switch as the only flow control mechanism and no gosub/return. The code in my program was structured a bit like the one you linked to. A massive switch on a sort of instruction pointer variable that got reassigned at the end of every case and an almost infinite loop around the switch. It got the job done.
I see you that you already have multiple fields in your class that you use to hold the variables. In that case, what you are doing is fine.
Otherwise, you can have 1 HashTable (maybe add in the C# indexor as a twist) to hold all of them, and your loop will end up like this:
foreach (string param in params.Split(';'))
{
string[] parts = param.Split('=');
string key = parts[0].Trim().ToLower();
string value = parts[1].Trim();
MyHashTable[key] = value;
}
The problem with this approach is that you should only have 1 type of value. For example, if your param list can contain both string and int types, it makes the code messier, especially you need to perform error checking and validation and stuff.
I personally would stick with what you already have.
You could use reflection for this:
Type t = this.GetType();
foreach (string param in params.Split(';'))
{
string[] parts = param.Split('=');
string key = parts[0].Trim().ToLower();
string value = parts[1].Trim();
t.GetProperty(key).SetValue(this, value, null);
}
For what it's worth, the WTF article was a WTF because its outer loop was completely useless, as noted in the article - it was just as easy, and more direct, just to set an index variable directly than to loop and test it.
Not sure if I understand either but it sounds like you're complicating yourself. Don't reinvent the wheel, use BCL classes as much as you can, these classes are proven to work efficiently and save you lots of time. Sounds like you could implement it with some sort of Dictionary<,> along with, like Guge suggested, Reflection.
I actually think the OP's code is fine. It's not perfect -- there might be simpler or cleaner ways to do it, but it effectively allows for readable mappings between member/property names and input-parameter names. It leaves your properties strongly typed (unlike the hashmap/dictionary solutions, unless your class has only one type for all its properties...) and gives you one fairly-obvious place to fix or add mappings.
Or Regex:
string parms = "param1=1;param2=2;param3=3";
string[] parmArr = parms.Split(';');
string parm1 = Regex.Replace(parmArr[0], "param1=", "");
string parm2 = Regex.Replace(parmArr[1], "param2=", "");
string parm3 = Regex.Replace(parmArr[2], "param3=", "");

Categories

Resources