-
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
SplitAt (split a sequence in two at a specified index) #315
Comments
We circle back a bit to the discussion in #306 . What to do when the index is out of range? Here you propose to be permissive. In general I argue for strictness, because I prefer my program tell me when instructions are unclear instead of making guesses for me. Of course, I'm not that strict on strictness (ha!), so I guess it depends on what the common use-cases would be. What use-cases do you see for this operator, that make permissiveness be a more sensible option? |
True.
If you look at each part of the split as simple buckets then permissiveness is acceptable. If you run a |
Based on @leandromoh's feedback in PR #316, I am inclined to revise this so that instead of splitting a sequence in two and returning a pivoted result of the two parts, it returns a sequence of sequences where the sub-sequences start at the given offset into the source sequence and stop before the next. Below is an initial draft of what this could look like: public static IEnumerable<IEnumerable<T>> SplitAt<T>(
this IEnumerable<T> source, params int[] offsets)
{
using (var oe = offsets.Concat(int.MaxValue).GetEnumerator())
{
oe.MoveNext();
var offset = oe.Current;
List<T> list = null;
foreach (var e in source.Index())
{
retry:
if (e.Key < offset)
{
if (list == null)
list = new List<T>();
list.Add(e.Value);
}
else
{
yield return list ?? Enumerable.Empty<T>();
offset = oe.MoveNext() ? oe.Current : -1;
list = null;
goto retry;
}
}
if (list != null)
yield return list;
while (oe.MoveNext())
yield return Enumerable.Empty<T>();
}
} This approach would be lazier and also support a source sequence that's infinite. The initial example would now read as: var xs = Enumerable.Range(1, 10);
var results =
from i in new[] { 0, 2, 5, 10, 20, -5 }
select xs.SplitAt(i).Fold((h, t) => new
{
Index = i,
Head = "[" + string.Join(",", h) + "]",
Tail = "[" + string.Join(",", t) + "]",
});
foreach (var result in results)
Console.WriteLine(result); Note that |
I'd like to propose a new operator that splits a sequence in two at a given index. The first sequence will contain all the items that appear before the index in the source sequence and the second will contain those items that appear at and after the index. A negative index would be allowed and would have the equivalent behavior of specifying an index of 0.
The follow table illustrates the splits that
SplitAt
will produce for a sample of indexes on a given source:Prototype
Example
Output
The text was updated successfully, but these errors were encountered: