是否有一种"好的"方法来消除列表元素的连续重复?
例:
["red"; "red"; "blue"; "green"; "green"; "red"; "red"; "yellow"; "white"; "white"; "red"; "white"; "white"]
Run Code Online (Sandbox Code Playgroud)
应该成为
["red"; "blue"; "green"; "red"; "yellow"; "white"; "red"; "white"]
Run Code Online (Sandbox Code Playgroud)
- "好"我的意思是对新用户和快速执行最具可读性和可理解性:)
Sim*_*ett 62
一个简单且易读的解决方案:
List<string> results = new List<string>();
foreach (var element in array)
{
if(results.Count == 0 || results.Last() != element)
results.Add(element);
}
Run Code Online (Sandbox Code Playgroud)
Ale*_*x J 19
你可以自己动手,linq风格.
// For completeness, this is two methods to ensure that the null check
// is done eagerly while the loop is done lazily. If that's not an issue,
// you can forego the check and just use the main function.
public static IEnumerable<T> NonConsecutive<T>(this IEnumerable<T> input)
{
if (input == null) throw new ArgumentNullException("input");
return NonConsecutiveImpl(input);
}
static IEnumerable<T> NonConsecutiveImpl<T>(this IEnumerable<T> input)
{
bool isFirst = true;
T last = default(T);
foreach (var item in input) {
if (isFirst || !object.Equals(item, last)) {
yield return item;
last = item;
isFirst = false;
}
}
}
Run Code Online (Sandbox Code Playgroud)
并用作
array.NonConsecutive().ToArray()
Run Code Online (Sandbox Code Playgroud)
优点是它被懒惰地评估,因此您可以在任何枚举上使用它而不必完全使用它,并将其与其他linq方法(例如:)链接array.Where(i => i != "red").NonConsecutive().Skip(1).ToArray().如果你没有这个要求而你只想使用数组,那么Simon Bartlett的解决方案可能会稍微提高一些性能.
有关为什么必须有两种方法的更多信息,请参见此处
您可以为此目的创建简单的通用方法,如下所示:
[编辑2](非常感谢Eric Lippert)
public static List<T> ExcludeConsecutiveDuplicates<T>(List<T> InputList)
{
object lastItem = null;
List<T> result = new List<T>();
for (int i = 0; i < InputList.Count; i++)
{
if (i==0 || Object.Equals(InputList[i],lastItem) != true)
{
lastItem = InputList[i];
result.Add((T)lastItem);
}
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
我认为这是使用 Linq 可以获得的最简单的结果:
colors.Where((color, i) => i == 0 || color != colors[i - 1]);
Run Code Online (Sandbox Code Playgroud)
您可以在 C# Interactive 中尝试一下:
> var colors = new[] { "red", "red", "blue", "green", "green", "red", "red", "yellow", "white", "white", "red", "white", "white" };
> colors.Where((color, i) => i == 0 || color != colors[i - 1])
WhereIterator { "red", "blue", "green", "red", "yellow", "white", "red", "white" }
Run Code Online (Sandbox Code Playgroud)
这里的技巧是使用Where()重载来接受带有索引的谓词,然后与原始数组中的前一项进行比较。
您可以在LINQ中执行此操作:
list.Aggregate(new List<string>(),
(current, next) => {
if (current.Length <= 0 || current[current.Length-1] != next) current.Add(next);
return current;
});
Run Code Online (Sandbox Code Playgroud)
实质上,这会创建一个初始为空的列表,在整个源列表中运行,并且只有在与目标列表的最后一项不同时才将项添加到目标列表.
没有LINQ,你可以轻松(可能更容易)做到这一点:
var target = new List<string>();
foreach (var item in list) {
if (target.Length <= 0 || target[target.Length-1] != item) target.Add(item);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7002 次 |
| 最近记录: |