c# - Is there an elegant LINQ solution for SomeButNotAll()? -


here i'm trying overall. clear, isn't homework or contest or anything. hopefully, i've made wording clear enough:

problem

given set of strings in same format, end in lowercase letter , not, return set of 1 of each string not end in lowercase letter, has @ least 1 identical string ending in lowercase letter.

example

to keep simple, let's string format \d+[a-z]?, common part number. given {1, 4, 3a, 1b, 3, 6c}, should receive permutation of {1, 3} because 1 , 3 have both element , without lowercase letter @ end.

alternate solution

you can view solution here.

one way thought of doing partition set elements , without lowercase letter suffix ({1, 4, 3} , {3a, 1b, 6c}), , return withoutsuffix.where(x => withsuffix.any(y => y.startswith(x))).

i have 2 problems this:

  1. i don't see way partition 2 sets, predicate regex.ismatch(input, "[a-z]$"). 2 thought of 2 similarly-defined variables each using where clause , doing regex matching twice per element, or transforming set store regex match results , forming 2 variables that. group...by doesn't seem play when need access both sets this, wrong there.

  2. although size small enough not care performance, going through withsuffix once per withoutsuffix element seems inelegant.

relevant solution

you can view solution here.

the other way came mind grab common prefix , optional suffix: {1 => {"", b}, 3 => {a, ""}, 4 => {""}, 6 => {c}}. accomplished capturing prefix , suffix regex ((\d+)([a-z])?) , grouping suffix prefix grouped.

from here, great do:

where grouped.somebutnotall(x => x == string.empty) select grouped.key 

or even:

where grouped.containssomebutnotall(string.empty) select grouped.key 

i create either of these, unfortunately, best can see in linq is:

where grouped.contains(string.empty) && grouped.any(x => x != string.empty) select grouped.key 

it feels super redundant. there better in linq already?

p.s. i'm open better approaches solving overall problem instead of making xy problem. elegance desired more performance, (maybe it's me) being plain wasteful still seems inelegant.

i don't think need regexen this. here's how it:

var withendings = new hashset<string>(); var withoutendings = new hashset<string>();  foreach (var s in input)     if(char.islower(s[s.length - 1]))          withendings.add(s.substring(0, s.length - 1));     else         withoutendings.add(s);  var result = withendings.intersect(withoutendings); 

Comments

Popular posts from this blog

shopping cart - Page redirect not working PHP -

php - How to modify a menu to show sub-menus -

python - Installing PyDev in eclipse is failed -