0

I'm reconstructing the following statement.

IEnumerable<String> 
  input = ...,
  filter = ...,
  output = input.Where(filter.Contains(element));

For now, it works as supposed to but the words matched this way need to be exact. In the language of my customer there are a lot of conjugations and a requirement is posted to use joker characters ("dog" should match "dog", "doggy" and "dogmatic").

I've suggested the following change. Now sure, though, if it can be regarded as smooth for the eyes. Can someone suggest an improvement or is it as good as it gets?

IEnumerable<String> 
  input = ...,
  filter = ...,
  output = input.Where(word => filter.Any(head => word.StartsWith(head)))

I was considering IEqualityComparer implementation but that's only for objects of the same type, while my condition is on String contra IEnumerable.

3
  • Are you sure the requirements are fine for checking with just StartsWith? Would "puppy" match in this case as well? Or what if they input "doggy"; should "dog" be a result as well? If everything is fine, I don't see a big issue about it being "smooth on the eyes"; it's not that bad. EDIT: If you want, you could move the filter.Any(head => word.Startswith(head)) into a separate Func<string, bool> delegate and pass that in so you'd have: Func<string, bool> myConstraint = word => filter.Any(head => word.StartsWith(head)); output = input.Where(myConstraint); Commented May 18, 2013 at 13:40
  • @ChrisSinclair No semantic matching required and most of the conjugations are suffixed so puppy and dog are (luckily) no match for doggy. I was worried that the double lambda expression would be perceived as as nasty syntax. Glad to be wrong on that, because I liked it (feeling sort of proud to get it expressed that way, haha). Commented May 18, 2013 at 14:04
  • 1
    @ChrisSinclair I'm kindly urging you to put remove the comment you've made and repost it as a reply to my question. I believe that suffice as an acceptable answer and I don't like living questions unchecked. Plus you get a cool +10 on your reputation too. Always nice to get some recognition. :) Commented May 23, 2013 at 5:28

1 Answer 1

1

Generally, what you already have as your LINQ statement is fine and I don't see a big issue with about it being "smooth on the eyes" (LINQ calls can often get even more out of hand than this).

If you want, you could move the filter.Any(head => word.Startswith(head)) into a separate Func<string, bool> delegate and pass that in:

Func<string, bool> myConstraint = word => filter.Any(head => word.StartsWith(head)); 
output = input.Where(myConstraint);

You can also move the constraint construction to a separate method which may open the door to some flexibility with your client if matching rules change or have to cover even more complicated cases:

private Func<string, bool> BuildConstraints()
{
    filter = ...,
    if (CheckEqualityOnly)
        return word => filter.Contains(word);
    else
        return word => filter.Any(head => word.StartsWith(head)); 
}

output = input.Where(BuildConstraints());
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.