We have this field in our database indicating a true/false flag for each day of the week that looks like this : '1111110'
I need to convert this value to an array of booleans.
For that I have written the following code :
char[] freqs = weekdayFrequency.ToCharArray();
bool[] weekdaysEnabled = new bool[]{
Convert.ToBoolean(int.Parse(freqs[0].ToString())),
Convert.ToBoolean(int.Parse(freqs[1].ToString())),
Convert.ToBoolean(int.Parse(freqs[2].ToString())),
Convert.ToBoolean(int.Parse(freqs[3].ToString())),
Convert.ToBoolean(int.Parse(freqs[4].ToString())),
Convert.ToBoolean(int.Parse(freqs[5].ToString())),
Convert.ToBoolean(int.Parse(freqs[6].ToString()))
};
And I find this way too clunky because of the many conversions.
What would be the ideal/cleanest way to convert this fixed length string into an Array of bool ??
I know you could write this in a for-loop but the amount of days in a week will never change and therefore I think this is the more performant way to go.
A bit of LINQ can make this a pretty trivial task:
var weekdaysEnabled = weekdayFrequency.Select(chr => chr == '1').ToArray();
Note that string already implements IEnumerable<char>, so you can use the LINQ methods on it directly.
In .NET 2
bool[] weekdaysEnabled1 =
Array.ConvertAll<char, bool>(
freqs,
new Converter<char, bool>(delegate(char c) { return Convert.ToBoolean(int.Parse(freqs[0].ToString())); }));
Related
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());
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.
I'm in a little bit of a bind. I'm working with a legacy system that contains a bunch of delimited strings which I need to parse. Unfortunately, the strings need to be ordered based on the first part of the string. The array looks something like
array[0] = "10|JohnSmith|82";
array[1] = "1|MaryJane|62";
array[2] = "3|TomJones|77";
So I'd like the array to order to look like
array[0] = "1|MaryJane|62";
array[1] = "3|TomJones|77";
array[2] = "10|JohnSmith|82";
I thought about doing a 2 dimensional array to grab the first part and leave the string in the second part, but can I mix types in a two dimensional array like that?
I'm not sure how to handle this situation, can anyone help? Thanks!
Call Array.Sort, but passing in a custom implementation of IComparer<string>:
// Give it a proper name really :)
public class IndexComparer : IComparer<string>
{
public int Compare(string first, string second)
{
// I'll leave you to decide what to do if the format is wrong
int firstIndex = GetIndex(first);
int secondIndex = GetIndex(second);
return firstIndex.CompareTo(secondIndex);
}
private static int GetIndex(string text)
{
int pipeIndex = text.IndexOf('|');
return int.Parse(text.Substring(0, pipeIndex));
}
}
Alternatively, convert from a string array into an array of custom types by splitting the string up appropriately. This will make life easier if you're going to do further work on the array, but if you only need to sort the values, then you might as well use the code above.
You did say that you need to parse the strings - so is there any particular reason why you'd want to parse them before sorting them?
new[] {
"10|JohnSmith|82",
"1|MaryJane|62",
"3|TomJones|77",
}.OrderBy(x => int.Parse(x.Split('|')[0]));
Use an ArrayList (http://msdn.microsoft.com/en-us/library/system.collections.arraylist_methods(VS.80).aspx) so you can sort it.
If the array is large, you will want to extract the initial integers all in one pass, so you are not parsing strings at every comparison. IMO, you really want to encapsulate the information encoded in the strings into a class first. Then sort the array of those objects.
Something like:
class Person {
int Index { get; }
string Name { get; }
int Age { get; } // just guessing the semantic meaning
}
So then:
Map your encoded string into an ArrayList of Person objects.
Then use ArrayList.Sort(IComparer) where your comparer only looks at the Index.
This will likely perform better than using parse in every comparison.
for lolz
Array.Sort(array, ((x,y) => (int.Parse(x.Split('|')[0]) < int.Parse(y.Split('|')[0])) ? -1 : (int.Parse(x.Split('|')[0]) > int.Parse(y.Split('|')[0])) ? 1 : 0));
If you have a string of "1,2,3,1,5,7" you can put this in an array or hash table or whatever is deemed best.
How do you determine that all value are the same? In the above example it would fail but if you had "1,1,1" that would be true.
This can be done nicely using lambda expressions.
For an array, named arr:
var allSame = Array.TrueForAll(arr, x => x == arr[0]);
For an list (List<T>), named lst:
var allSame = lst.TrueForAll(x => x == lst[0]);
And for an iterable (IEnumerable<T>), named col:
var first = col.First();
var allSame = col.All(x => x == first);
Note that these methods don't handle empty arrays/lists/iterables however. Such support would be trivial to add however.
Iterate through each value, store the first value in a variable and compare the rest of the array to that variable. The instant one fails, you know all the values are not the same.
How about something like...
string numArray = "1,1,1,1,1";
return numArrray.Split( ',' ).Distinct().Count() <= 1;
I think using List<T>.TrueForAll would be a slick approach.
http://msdn.microsoft.com/en-us/library/kdxe4x4w.aspx
Not as efficient as a simple loop (as it always processes all items even if the result could be determined sooner), but:
if (new HashSet<string>(numbers.Split(',')).Count == 1) ...
I have a List (Foo) and I want to see if it's equal to another List (foo). What is the fastest way ?
From 3.5 onwards you may use a LINQ function for this:
List<string> l1 = new List<string> {"Hello", "World","How","Are","You"};
List<string> l2 = new List<string> {"Hello","World","How","Are","You"};
Console.WriteLine(l1.SequenceEqual(l2));
It also knows an overload to provide your own comparer
Here are the steps I would do:
Do an object.ReferenceEquals() if true, then return true.
Check the count, if not the same, return false.
Compare the elements one by one.
Here are some suggestions for the method:
Base the implementation on ICollection. This gives you the count, but doesn't restrict to specific collection type or contained type.
You can implement the method as an extension method to ICollection.
You will need to use the .Equals() for comparing the elements of the list.
Something like this:
public static bool CompareLists(List<int> l1, List<int> l2)
{
if (l1 == l2) return true;
if (l1.Count != l2.Count) return false;
for (int i=0; i<l1.Count; i++)
if (l1[i] != l2[i]) return false;
return true;
}
Some additional error checking (e.g. null-checks) might be required.
Something like this maybe using Match Action.
public static CompareList<T>(IList<T> obj1, IList<T> obj2, Action<T,T> match)
{
if (obj1.Count != obj2.Count) return false;
for (int i = 0; i < obj1.Count; i++)
{
if (obj2[i] != null && !match(obj1[i], obj2[i]))
return false;
}
}
Assuming you mean that you want to know if the CONTENTS are equal (not just the list's object reference.)
If you will be doing the equality check much more often than inserts then you may find it more efficient to generate a hashcode each time a value is inserted and compare hashcodes when doing the equality check. Note that you should consider if order is important or just that the lists have identical contents in any order.
Unless you are comparing very often I think this would usually be a waste.
One shortcut, that I didn't see mentioned, is that if you know how the lists were created, you may be able to join them into strings and compare directly.
For example...
In my case, I wanted to prompt the user for a list of words. I wanted to make sure that each word started with a letter, but after that, it could contain letters, numbers, or underscores. I'm particularly concerned that users will use dashes or start with numbers.
I use Regular Expressions to break it into 2 lists, and them join them back together and compare them as strings:
var testList = userInput.match(/[-|\w]+/g)
/*the above catches common errors:
using dash or starting with a numeric*/
listToUse = userInput.match(/[a-zA-Z]\w*/g)
if (listToUse.join(" ") != testList.join(" ")) {
return "the lists don't match"
Since I knew that neither list would contain spaces, and that the lists only contained simple strings, I could join them together with a space, and compare them.