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:
i don't see way partition 2 sets, predicate
regex.ismatch(input, "[a-z]$"). 2 thought of 2 similarly-defined variables each usingwhereclause , doing regex matching twice per element, or transforming set store regex match results , forming 2 variables that.group...bydoesn't seem play when need access both sets this, wrong there.although size small enough not care performance, going through
withsuffixonce perwithoutsuffixelement 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
Post a Comment