-
Notifications
You must be signed in to change notification settings - Fork 419
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
TrySingle : xs → Zero | (x, One) | Many #540
Comments
Just curious, |
True, that could be the implementation perhaps. |
If we are going to add this, I would like to avoid introducing the public static TResult
TrySingle<T, TCardinality, TResult>(this IEnumerable<T> values,
TCardinality zero, TCardinality one, TCardinality many,
Func<TCardinality, T, TResult> resultSelector) In other words, the caller defines the three cardinality cases and the public static Cardinality TrySingle<T>(this IEnumerable<T> values, out T result)
{
Cardinality cardinality;
(cardinality, result) =
values.TrySingle(Cardinality.Zero,
Cardinality.One,
Cardinality.Many,
ValueTuple.Create);
return cardinality;
} |
very nice suggestion, but I think Cardinality is overkill. what about this? public static IEnumerable<T> ExtractFirst<T>(this IEnumerable<T> values, out T result)
{
result = default;
using (var enumerator = values.GetEnumerator())
{
if (enumerator.MoveNext())
{
result = enumerator.Current;
return GetRest();
}
return null;
IEnumerable<T> GetRest()
{
while (enumerator.MoveNext())
{
yield return enumerator.Current;
}
}
}
} If null is returned, source contains no element. returned enumerable is like alternative signature: public static T ExtractFirst<T>(this IEnumerable<T> values, out IEnumerable<T> rest);
public static bool ExtractFirst<T>(this IEnumerable<T> values, out T first, out IEnumerable<T> rest); The last signature works nicely with source.ExtractFirst(out var first, out var rest)
? // work with first and rest
: Enumerable.Empty<T>(); |
@MkazemAkhgary Your
If these are the rules, then it suffices to have something like this: public static IEnumerator<T> TryMoveToFirst<T>(this IEnumerable<T> values)
{
var enumerator = values.GetEnumerator();
try
{
return enumerator.MoveNext() ? enumerator : null;
}
catch
{
enumerator.Dispose();
throw;
}
} The |
Good point on disposed enumerator. I totally missed that. apart from that changing enumerator to enumerable may cause underlying enumerator to never get disposed if the enumerable is not consumed completely. My intention how ever was to make the syntax as short as possible. having to dispose the enumerator on caller makes some clutter. I have to admit that if c# evolves some pattern matching in future (switch expressions) then usage with This one has limited usage but it fixes the problems that you mentioned. public static bool ExtractFirst<T>(this IEnumerable<T> values, out T first, out T[] rest);
public static bool ExtractFirst<T>(this IEnumerable<T> values, int restLength, out T first, out T[] rest); |
#590 could address this too and since there's been no further follow up from @jimmcslim, I'm going to close this issue. |
Re-opening this issue now that there is a PR (#612) open for it. |
I'm wondering whether the community would think that
TrySingle
would be a useful addition to MoreLINQ.Where the behaviour of
TrySingle
is to attempt to return the first, single element from the enumerable. If the enumerable has a single element,out result
is populated with the item, andCardinality.One
is returned. However, if there are zero items in the enumerable then the method returnsCardinality.Zero
; if there are multiple items in the enumerable then the method returnsCardinality.Many
. In both of these cases theout result
is null.A consumer of this method can then distinctly handle the
Zero
orMany
cases in whichever special way is required.I'm happy to submit a PR if this is worthwhile.
The text was updated successfully, but these errors were encountered: