假设我有这样的列表:
int[] list = { 1, 2, 3, 3, 1 };我想要的是删除重复的,立即跟随相同的数字。因此,在这种情况下,我想删除3,但不是1。
因此,新的列表应该是:{1, 2, 3, 1}
另一个例子是这个列表:{2, 7, 7, 7, 2, 6, 4},它将变成{2, 7, 2, 6, 4}。
我能用LINQ做这个吗?
发布于 2017-06-24 19:26:35
如果您想使用现有的LINQ方法,可以使用Aggregate,但是这种方法将失去惰性。您可以编写自己的扩展方法:
public static IEnumerable<T> RemoveConsecutiveDuplicates<T>(this IEnumerable<T> source, IEqualityComparer<T> comp = null)
{
comp = comp ?? EqualityComparer<T>.Default;
using (var e = source.GetEnumerator())
{
if (e.MoveNext())
{
T last = e.Current;
yield return e.Current;
while (e.MoveNext())
{
if (!comp.Equals(e.Current, last))
{
yield return e.Current;
last = e.Current;
}
}
}
}
}发布于 2017-06-24 19:29:45
如果您坚持使用LINQ进行此操作,则可以使用Aggregate
var result = array.Aggregate(new List<int>(), (a, b) =>
{
if (!a.Any() || a.Last() != b)
a.Add(b);
return a;
});但这并不一定是最有效的解决方案,因为在每次迭代中都有Any和Last。比较以前的迭代值和当前的迭代值的简单foreach将执行得更好。
发布于 2017-06-24 19:26:13
您可以像这样从PairWise中使用MoreLINQ:
var result =
new[] {list[0]}
.Concat(
list
.Pairwise((x, y) => new {Item = y, Same = x == y})
.Where(x => !x.Same)
.Select(x => x.Item))
.ToArray();PairWise允许您获得一个序列,该序列的结果是对原始序列中的每个项及其前面的项应用函数(对第一个项的期望)。
我在这里要做的是,对于每一项(期望第一项),我将得到项目本身,并得到一个布尔值(Same),指示该项目是否等于它前面的项。然后,我对序列进行过滤,只获取每个项都不等于前面项的项。然后,我只是简单地将最初列表中的第一项添加到新的序列中。
注意:不要忘记处理list为空的情况。
https://stackoverflow.com/questions/44740066
复制相似问题