如何优雅实现类似String.Split的整数数组拆分功能?
Split Method for Integer Arrays (Mirroring String.Split) Great question! It's true that most resources focus on String.Split, but a similar method for integer arrays is super useful—and while your existing code gets the job done, we can definitely make it more elegant and readable.
Let's start by noting your original implementation works, but managing skip and take adds unnecessary complexity. Here are two cleaner approaches that align with C#'s idiomatic patterns:
Approach 1: Simple Foreach Loop (Most Readable)
This method uses a temporary list to build each segment as we iterate, eliminating the need for tracking indices and lengths. It's straightforward and easy to debug:
public int[][] Split(int[] arr, int separator) { var resultSegments = new List<int[]>(); var currentSegment = new List<int>(); foreach (int number in arr) { if (number == separator) { // Only add non-empty segments to the result if (currentSegment.Count > 0) { resultSegments.Add(currentSegment.ToArray()); currentSegment.Clear(); } } else { currentSegment.Add(number); } } // Don't forget to add the final segment if it's not empty if (currentSegment.Count > 0) { resultSegments.Add(currentSegment.ToArray()); } return resultSegments.ToArray(); }
Why this works better:
- No confusing index math (
skip/takeare gone entirely) - Linear flow makes the logic easy to follow at a glance
- Explicitly handles the final segment without checking array bounds
- Matches
String.Split's default behavior (ignores empty segments from consecutive separators)
Approach 2: LINQ's Aggregate (Functional Style)
If you prefer a more functional approach, LINQ's Aggregate lets us encapsulate the state (current segment + result list) in a single pass:
public int[][] Split(int[] arr, int separator) { return arr.Aggregate( // Initialize our state: current segment and result list new { CurrentSegment = new List<int>(), Result = new List<int[]>() }, // Update state for each element (state, number) => { if (number == separator) { if (state.CurrentSegment.Count > 0) { state.Result.Add(state.CurrentSegment.ToArray()); state.CurrentSegment.Clear(); } } else { state.CurrentSegment.Add(number); } return state; }, // Finalize: add the last segment and convert to array state => { if (state.CurrentSegment.Count > 0) state.Result.Add(state.CurrentSegment.ToArray()); return state.Result.ToArray(); }); }
When to use this:
- If you want to avoid mutable state in your main code (though the state is encapsulated here)
- It's a concise way to express the logic in a single LINQ chain
Both of these approaches will produce exactly the output you shared:
For Split(arr1, 0):
3,3 2,4,3,2
For Split(arr2, 8):
5,7,9 7,4
内容的提问来源于stack exchange,提问作者Alaa Jabre

