Reputation: 39454
I have a list of String:
List<String> names = new List<String> { "aa", "Bb", "cC", "DD" }
And a list of Categories:
List<Category> categories = service.GetAllCategories();
Where Category is the following class:
public class Category {
public int Id { get; set; }
public string Name { get; set; }
}
I need to know if all names are found in categories (using case insensitive):
bool check = names.All(x => categories.Any(y => x.ToLower() == y.Name.ToLower()):
Is there a way with better performance then this? I am not sure if Any inside All is the best approach.
Is there an alternative to using ToLower to get case insensitive?
Upvotes: 1
Views: 92
Reputation: 13676
Is there a way with better performance then this? I am not sure if Any inside All is the best approach
It depends on number of elements in collection. For small collections it could be ok to use O(N2)
complexity as this operation might take a few ms.
For bigger collections and to improve performance you can use HashSet<T>
:
var categoryNames = new HashSet<string>(categories.Select(c => c.Name));
bool check = names.All(x => categoryNames.Contains(x.ToLower()):
This .Contains
will be a fast O(1) lookup changing overall complexity to O(N) but it comes with the price of time needed to create an instance of HashSet<T>
.
-
Is there an alternative to using ToLower to get case insensitive?
Yes, you can use one of string.Equals
overload that accepts StringComparison argument :
y.Equals(x, StringComparison.CurrentCultureIgnoreCase);
Upvotes: 2
Reputation: 460208
1) Yes, you can use !Except
+ Any
which is more efficient because it's using a set.
bool check = !names.Except(categories.Select(c => c.Name), StringComparer.CurrentCultureIgnoreCase).Any();
2) Don't compare in a case insensitive manner by using ToLower
but the right StringComparer
.
Upvotes: 8