0

I got collection of structures with string property. Given an array of strings I want to check if there is any structure which inner string matches some of them in the array. I did it in this way:

    struct S
    {
        public string s { get; set; }
    }

    private List<S> List = new List<S>(); // populated somewhere else

    public bool Check(params string[] arr)
    {
        return (from s1 in List
                select s1.s into s1
                where !string.IsNullOrEmpty(s1)
                join s2 in arr on s1.ToLowerInvariant() equals s2.ToLowerInvariant() select s1).Any();
    }

Simply, I just want to achieve StringComparison.InvariantCultureIgnoreCase. Is it a proper way to do so? Is it efficient?

bottaio
  • 4,963
  • 3
  • 19
  • 43

3 Answers3

2

You could also use a HashSet, which should have a similar performance to the Dictionary:

var set = new HashSet<string>(
     List.Select(x => x.s),
     StringComparer.InvariantCultureIgnoreCase);

return arr.Any(set.Contains);
Charles Mager
  • 25,735
  • 2
  • 35
  • 45
  • The nice bit here is that you're telling the hash which comparison to use, rather than converting every string. – Rawling Jul 30 '15 at 07:16
1

The most efficient way to do so is to create a dictionary based on the collection of structures you have.

var dictionary = list.ToDictionary(item=>item.s.ToLowerInvariant(),item=>item);

Then you could loop through your array of strings (O(n)):

foreach(item in array)
{
    S value;
    // This is an O(1) operation.
    if(dictionary.TryGetValue(item.ToLowerInvariant(), out value)
    {
        // The TryGetValue returns true if the an item 
        // in the dictionary found with the specified key, item
        // in our case. Otherwise, it returns false.
    }
}
Christos
  • 53,228
  • 8
  • 76
  • 108
  • @greenshade Exactly ! However there is a subtle difference, which you should be aware of. Please have a look here http://stackoverflow.com/questions/876656/difference-between-dictionary-and-hashtable. – Christos Jul 31 '15 at 04:55
0

You could do something like this

class Program
{
    struct MyStruct
    {
        public string Data { get; set; }
    }

    static void Main(string[] args)
    {
        var list = new List<MyStruct>();
        list.Add(new MyStruct { Data = "A" });
        list.Add(new MyStruct { Data = "B" });
        list.Add(new MyStruct { Data = "C" });


        var arr = new string[] { "a", "b" };

        var result = (from s in list
                      from a in arr
                      where s.Data.Equals(a, StringComparison.InvariantCultureIgnoreCase)
                      select s).ToArray();
    }
}
Tsef
  • 1,018
  • 9
  • 22