我想根据另一个列表的条目将现有的排序列表拆分为多个子列表。
假设我有一个这样的数组:
List<int> myList = [1,3,7,23,56,58,164,185];
和另一个列表,它定义了应分割哪些地方myList
:
List<int> borders = [4,59,170];
获取嵌套列表的最短方法是将myList
拆分为borders
中定义的值,例如:
[[1,3],[7,23,56,58],[164],[185]]
我已经通过手动循环遍历列表来解决它,但我可以想象使用Linq更容易和更短。
编辑:有一个简化:数字不能与边框相同,因此myList
和borders
中的数字不可能同时包含在内。
答案 0 :(得分:14)
由于您希望将数字分组到不同的组中,因此您需要使用GroupBy
。困难只是你用作关键的东西。为此,您可以使用小于该数字的最大边框值。这假设borders
已排序:
List<int> myList = new List<int> { 1, 3, 7, 23, 56, 58, 164, 185 };
List<int> borders = new List<int> { 4, 59, 170 };
var groups = myList.GroupBy(i => borders.LastOrDefault(x => x < i));
foreach (var group in groups)
{
Console.WriteLine("{0}: {1}", group.Key, string.Join(", ", group));
}
这会产生以下输出:
0: 1, 3
4: 7, 23, 56, 58
59: 164
170: 185
请注意,这不是最有效的解决方案,因为它会为myList
中的每个元素搜索适当的边框键。如果您的列表按照您的示例进行排序,那么同时循环两个列表并将myList
的数字与当前或下一个border元素匹配会更有效。因此,此解决方案为O(n * m)
,而解决方案O(n)
是可行的。从好的方面来说,这允许myList
完全未排序。
对于那些对O(n)解决方案感兴趣的人,这里有一个可能的方法,这只是分组序列的一般方法:
List<List<int>> groups = new List<List<int>>();
List<int> group = null;
int k = -1;
foreach (int num in myList)
{
if (k < 0 || num > borders[k])
{
group = new List<int>();
groups.Add(group);
k++;
}
group.Add(num);
}