c# - 使用 LINQ 替换 C# 中可枚举的一个元素
问题描述
我在使用 linq 方面很新,并且已经玩了几天了。我目前的问题是,我在这个可枚举中有一个可枚举和一个特定对象,应该用一个新实例替换它。
使用 for 循环,我会像这样实现它:
public IEnumerable<Foo> ReplaceFirst(IEnumerable<Foo> enumerable, Foo obj)
{
Foo[] array = enumerable.ToArray();
bool used = false;
for (int i = 0; i < array.Length; i++)
if(array[i] == obj)
{
array[i] = new Foo();
used = true;
break;
}
if (used)
return array;
else
throw new ArgumentException("obj not found in enumerable");
}
现在我正在寻找一个带有 linq 的实现。到目前为止我发现的是:
public IEnumerable<Foo> ReplaceFirst(IEnumerable<Foo> enumerable, Foo obj)
{
return enumerable.Contains(obj)
? locatedPieces.TakeWhile(current => current != obj)
.Append(new Foo())
.Concat(enumerable.SkipWhile(current => current != obj)
.Skip(1))
: throw new ArgumentException("obj not found in enumerable");
}
但我不太确定这个实现是否有效,因为它必须至少迭代可枚举三次(在Contains、TakeWhile和SkipWhile处)。
有没有更好的方法来用 linq 实现这个功能,或者我应该继续使用 for-loop 变体?
解决方案
我建议为此创建一个扩展方法,如下所示:
public static IEnumerable<T> Replace<T>(this IEnumerable<T> source, T oldVal, T newVal)
{
return source.Select(e => EqualityComparer.Default.Equals(e, oldVal) ? newVal : e);
}
这将遍历源并返回源元素,除了那些 == oldValue 的元素。
这也使用延迟执行。仅当您开始枚举生成的 IEnumerable 时才会枚举源。因此,如果您在调用此新的 Replace 扩展后更改源序列,则生成的序列也将产生此更改。
推荐阅读
- c++ - 错误:A 类不是 B 类 C++ 的基础
- python-3.x - How to scrape a JavaScript website using Python with Selenium
- python - Customizing columns for export to csv with BeautifulSoup4
- python - 附加功能包括一个列表
- reason - 错误:未找到或构建包原因反应
- python - 我怎么知道python中生成的随机数?
- python - Expand a dict containing list items into a list of dict pairs
- python - Twisted deferred 上的生成器回调
- python - Python Selenium:我无法单击此退出按钮
- c# - 在 ASP.NET MVC 中使用 AJAX 方法时使用 C# 控制器重定向到页面