如何基于另一列表的顺序拆分列表?求LINQ/函数式实现方案
Got it, let's tackle this problem with LINQ and functional programming principles—no iterative queue logic required! The goal is to split a source list into sublists by cycling through a reference order list: each sublist collects elements as we traverse the reference order, and we repeat this until the source list is fully processed.
Ordered List Splitting with LINQ/Functional Style
Solution Code
using System; using System.Collections.Generic; using System.Linq; public class ListSplitter { public static List<List<int>> SplitByOrder(List<int> source, List<int> order) { // Use Aggregate to accumulate results and track unprocessed elements return source.Aggregate( new { Results = new List<List<int>>(), Remaining = source.AsEnumerable() }, (accumulator, _) => { // If there's nothing left to process, keep the current state if (!accumulator.Remaining.Any()) return accumulator; // Cycle through the order list to build one sublist var (currentSublist, newRemaining) = order.Aggregate( (Sublist: new List<int>(), Remaining: accumulator.Remaining), (currentState, orderItem) => { if (!currentState.Remaining.Any()) return currentState; // Grab the element if it matches the current order item if (currentState.Remaining.First() == orderItem) { currentState.Sublist.Add(currentState.Remaining.First()); return (currentState.Sublist, currentState.Remaining.Skip(1)); } return currentState; }); // Add the sublist to results only if it's not empty if (currentSublist.Any()) { accumulator.Results.Add(currentSublist); } return new { accumulator.Results, Remaining = newRemaining }; }, finalState => finalState.Results); } public static void Main() { // Test with List B from your example var orderB = new List<int> { 4, 5, 6, 0, 1, 2, 3 }; var nums = new List<int> { 2, 5, 6, 2, 2, 4 }; var result = SplitByOrder(nums, orderB); // Print the output to verify foreach (var sublist in result) { Console.WriteLine($"[{string.Join(", ", sublist)}]"); } // Expected output: // [2] // [5, 6, 2] // [2] // [4] } }
How This Works
Let's break down the key parts in plain terms:
- Outer Aggregate: We use the source list to drive iterations (we don't use the individual elements, just the count to keep going until everything's processed). This tracks two things: the sublists we've already created, and the elements left to process.
- Inner Aggregate: For each iteration, we loop through the reference order list. If the next unprocessed element from the source matches the current order item, we add it to the sublist and mark it as processed.
- State Update: After each full pass through the order list (or if we run out of elements early), we add the non-empty sublist to our results and update the remaining elements for the next round.
Alternative Recursive Functional Approach
If you prefer a more pure functional recursive style, here's another version:
public static List<List<int>> SplitByOrderRecursive(List<int> source, List<int> order) { // Base case: nothing left to process if (!source.Any()) return new List<List<int>>(); // Process one full pass through the order list var (sublist, remaining) = order.Aggregate( (Sublist: new List<int>(), Remaining: source.AsEnumerable()), (currentState, orderItem) => { if (!currentState.Remaining.Any()) return currentState; if (currentState.Remaining.First() == orderItem) { currentState.Sublist.Add(currentState.Remaining.First()); return (currentState.Sublist, currentState.Remaining.Skip(1)); } return currentState; }); // Build the result by adding this sublist and recursing on remaining elements var result = new List<List<int>> { sublist }; result.AddRange(SplitByOrderRecursive(remaining.ToList(), order)); // Filter out any empty sublists (cleanup for final passes that don't collect anything) return result.Where(s => s.Any()).ToList(); }
Test with List A
To confirm it works for your first example, just swap in List A:
var orderA = new List<int> {1,2,3,4,5,6,0}; var nums = new List<int> {2,5,6,2,2,4}; var resultA = SplitByOrder(nums, orderA); // Expected output: [2, 5, 6], [2], [2, 4]
Both implementations will correctly generate the expected sublists for either reference order.
内容的提问来源于stack exchange,提问作者firefly
相关产品推荐
相关产品推荐

