-
Notifications
You must be signed in to change notification settings - Fork 416
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
Filter out nulls given a T? (struct) sequence, returning just T values #609
Comments
There's already public static IEnumerable<T> WhereHasValue<T>(this IEnumerable<T?> source)
where T : struct =>
source.Choose(e => e is T v ? (true, v) : default); I believe that if you start using static partial class Nullable
{
public static (bool HasValue, T Value) Deconstruct<T>(T? nullable) where T : struct =>
nullable.HasValue ? (true, nullable.Value) : default;
} This is more general and independent of whether "O,l,2,3,4,S,6,7,B,9".Split(',')
.Select(s => int.TryParse(s, out int n) ? (int?)n : null)
.Select(Nullable.Deconstruct)
.Choose(x => x)
.ForEach(Console.WriteLine); // prints 2, 3, 4, 6, 7 & 9 on separate lines The above example is somewhat artificial because I'd write it simply as: "O,l,2,3,4,S,6,7,B,9".Split(',')
.Select(s => int.TryParse(s, out int n) ? (true, n) : default)
.Choose(x => x)
.ForEach(Console.WriteLine); but my point is that if you have a sequence of By the way, if you use my Optuple library, then you get "O,l,2,3,4,S,6,7,B,9".Split(',')
.Select(s => int.TryParse(s, out int n) ? (int?)n : null)
.Select(Option.ToOption)
.Choose(x => x)
.ForEach(Console.WriteLine); or just: "O,l,2,3,4,S,6,7,B,9".Split(',')
.Select(s => int.TryParse(s, out int n) ? Some(n) : default)
.Choose(x => x)
.ForEach(Console.WriteLine); Optuple is non-viral as it introduces or imposes no new data type that leaks into your API. If you're interested in the discussion surrounding the design of I hope the above demonstrates that public static IEnumerable<T> NonNull<T>(this IEnumerable<T?> source)
where T : struct =>
source.Choose(e => e switch { null => default, T v => (true, v) });
public static IEnumerable<T> NonNull<T>(this IEnumerable<T> source) =>
source.Choose(e => e switch { null => default, T v => (true, v) }); I'd like to get the thoughts of @fsateler and @leandromoh on this. I am hesitant to add the second overload because the signature doesn't do justice now that we can express nullable reference types since C# 8 because technically speaking, you'd like to say that public static IEnumerable<TValue>
NonNull<T, TValue>(
this IEnumerable<T> source,
Func<T, TValue> valueSelector)
where TValue : notnull =>
source.Choose(e => e switch { null => default, T v => (true, valueSelector(v)) }); Even with the added constraint, public static IEnumerable<TValue>
NonNull<T, TValue>(
this IEnumerable<T> source,
Func<T, TValue> valueSelector)
where T : class
where TValue : notnull =>
source.Choose(e => e switch { null => default, T v => (true, valueSelector(v)) }); Anyway, this is all odd enough to simply avoid overloading. |
@atifaziz since this method is as simple as |
I think we can close this solely on the basis that there's been no follow-up from @fowl2 so this issue can be considered stale. |
Hi @atifaziz, what follow-up were you expecting? My understanding this was waiting until the c# 8.0's nullability annotations were released so that it could be done as well as possible with respect to that. PS. Thanks again for this work! |
@fowl2 Perhaps the right word was reaction, rather than follow-up, to the ideas and thoughts I laid out. For one, if
As I said, to do this right would make it ugly unless someone else has a better idea. If you're going to need an artificial projection, you might as well go with I was also waiting to hear from @leandromoh and @fsateler, and while @leandromoh has spoken his mind and voted that this is not worth the trouble, I am guessing that @fsateler is just occupied. |
This is better than just writng
Where(a => a.HasValue)
because it returnsT
instead ofT?
.The text was updated successfully, but these errors were encountered: