我有一个int数组,它是来自多个类似数组的连接数组,所有数组都从1开始。
1,2,3,4 1,2 1,2,3 1,2,
int[] list = { 1, 2, 3, 4, 1, 2, 1, 2, 3, 1, 2 };
我想要达到的目的是得到结果的“最后一组”{1,2}。
尝试:
int[] list = { 1, 2, 3, 4, 1, 2, 1, 2, 3, 1, 2 };
List<int> lastSet = new List<int>();
var totalSets = list.Count(x => x == 1);
int encounter = 0;
foreach (var i in list)
{
if (i == 1)
encounter += 1;
if (encounter == totalSets)
lastSet.Add(i);
}
lastSet.ToList().ForEach(x => Console.WriteLine(x));
有没有更好的方法来使用LINQ实现这一点,可能是SkipWhile
,GroupBy
,Aggregate
?
答案 0 :(得分:1)
如果您可以将列表设为实际List<int>
,或者如果您不想通过.ToList()
创建列表副本,则可以执行以下操作:
var list = new[]{ 1, 2, 3, 4, 1, 2, 1, 2, 3, 1, 2 }.ToList();
var lastSet = list.Skip(list.LastIndexOf(1)).ToList();
否则,Aggregate
可以正常工作,但这有点难看:
var lastSet = list.Aggregate(new List<int>{1}, (seed, i) => {
if(i == 1) {seed.Clear(); }
seed.Add(i);
return seed;
})
正如dtb指出的那样,你可以使用Array.LastIndexOf而不是创建一个List:
var list = new[]{ 1, 2, 3, 4, 1, 2, 1, 2, 3, 1, 2 };
var lastSet = list.Skip(Array.LastIndexOf(list, 1)).ToList();
答案 1 :(得分:1)
适用于任何IEnumerable
(但速度低于直接List
版本)
var sub = list.Reverse<int>()
.TakeWhile(i => i != 1)
.Concat(new[]{1})
.Reverse<int>();
如果您愿意,可以在结果上运行ToArray()
。
答案 2 :(得分:1)
使用下面的GroupAdjacent Extension Method,您可以将列表拆分为以1开头的序列,然后选择最后一个序列:
var result = list.GroupAdjacent((g, x) => x != 1)
.Last()
.ToList();
与
public static IEnumerable<IEnumerable<T>> GroupAdjacent<T>(
this IEnumerable<T> source, Func<IEnumerable<T>, T, bool> adjacent)
{
var g = new List<T>();
foreach (var x in source)
{
if (g.Count != 0 && !adjacent(g, x))
{
yield return g;
g = new List<T>();
}
g.Add(x);
}
yield return g;
}
答案 3 :(得分:1)
LINQ被高估了:
int[] list = { 1, 2, 3, 4, 1, 2, 1, 2, 3, 1, 2 };
int pos = Array.LastIndexOf(list, 1);
int[] result = new int[list.Length - pos];
Array.Copy(list, pos, result, 0, result.Length);
// result == { 1, 2 }
现在可读性提高100%:
int[] list = { 1, 2, 3, 4, 1, 2, 1, 2, 3, 1, 2 };
int[] result = list.Slice(list.LastIndexOf(1));
// result == { 1, 2 }
,其中
static int LastIndexOf<T>(this T[] array, T value)
{
return Array.LastIndexOf<T>(array, value);
}
static T[] Slice<T>(this T[] array, int offset)
{
return Slice(array, offset, array.Length - offset);
}
static T[] Slice<T>(this T[] array, int offset, int length)
{
T[] result = new T[length];
Array.Copy(array, offset, result, 0, length);
return result;
}