-
Notifications
You must be signed in to change notification settings - Fork 4.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
API proposal: StringSplitOptions.TrimEntries #31038
Comments
👀 I'm suspicious whenever I see |
A frequent usage for me is return element?.InnerText?.Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyOrWhiteSpaceEntries);
return element?.InnerText?.Split(',', StringSplitOptions.RemoveEmptyEntries).Where(value => !string.IsNullOrWhiteSpace(value)).Select(value => value.Trim()).ToArray(); Another real case(InnerText) <Exclude>
[lib]ns1.*,
[lib]ns2.*
</Exclude> or <Exclude> </Exclude>
Why? When you work with command line parameters or file(i.e. runsettings file parameters) parameters usually you use this way, not hot loop or csv parsing for sure. |
API review - see if there's any usage of |
I dug into this a bit further, and there doesn't seem to be much of a scenario for having a separate
In both cases the call sites could've used simply |
namespace System
{
[Flags]
public enum StringSplitOptions
{
// Existing:
// None = 0,
//RemoveEmptyEntries = 1,
// New:
TrimEntries = 2
}
} |
@GrabYourPitchforks I was going to note that #295 would need updating for "TrimEntries" but I don't see that API accepting StringSplitOptions. I assume that was intentional (I didn't read all of #934) |
@danmosemsft For spans, I'm still partial to a design that allows me to write something like the following. It gets rid of the whole iterator mess for some common scenarios. ROS<char> span = GetName(); // "Doe, John"
(var lastName, var firstName) = span.Split(',', StringSplitOptions.TrimEntries);
// At this point, lastName := "Doe" and firstName := "John" Per the "accepted" proposal at #934 (comment), there are no split options being passed in. So the changes in this issue shouldn't affect that PR. |
@GrabYourPitchforks I'm unclear how that would work, if Split resulted in 50 fragments, would I receive a 50 element tuple? Do you know why #934 did not include StringSplitOptions? It seems like a natural extension - either we would want #934 plus SSO, or something different entirely. |
@danmosemsft it's equivalent to passing in a "max elements" parameter and then decomposing the result into that number of components. That is: (var lastName, var firstName) = span.Split(','); // essentially equivalent to Split(',', maxValues: 2);
ROS<char> span = "Doe, John, III";
(var lastName, var firstName) = span.Split(',', SSO.Trim);
// lastName := "Doe"
// firstName := "John, III" Which is generally what most callers want when doing this kind of split. Calling Honestly I've tried to avoid thinking about #934. The API feels very wrong to me, but I'm having trouble vocalizing why. |
To your question re: |
I'm not understanding what the API signature would be. You're saying you could write one method that would support any decomposition, dictated by the call site? How do you do that without explicitly adding a decompose method for each desired arity? |
This being said, I'll carry on with #295 to unblock existing scenarios, and we extend/add more API as needed. |
How many times have we all written the below code?
Even just a cursory search of our own Framework reference sources shows that this is a common pattern:
I propose adding an enum value
StringSplitOptions.TrimEntries
that would make this pattern a bit easier for folks by eliminating the need for developers to callTrim
.The behavior of
string.Split
and related APIs would be as follows:If None or RemoveEmpyEntries is provided, the behavior of
string.Split
under this proposal is unchanged from its behavior today.If TrimEntries is provided by itself, the
string.Split
method performs the equivalent of callingstring.Trim()
on each element of the returned array. That is, no element in the returned array will have leading or trailing whitespace. The array may contain zero-length strings for entries.If TrimEntries and RemoveEmptyEntries are both provided, the entries are trimmed first, and then zero-length entries are removed from the returned array.
Adding this enum value may be considered a breaking change if we expect that third-party components aside from
string.Split
are consuming theStringSplitOptions
enum, not simply generating the value. In theory any such third-party components should be checking their inputs and rejecting unknown flags.The text was updated successfully, but these errors were encountered: