如何替换集合中的元素 [英] How to replace an element in a Collection
问题描述
我想做的事情看起来非常简单-我想在 ICollection< T>
中找到一个满足给定谓词的元素,然后将其替换为另一个。在C ++中,我会这样写:
for(auto& element:collection){
if(predicate(elem)){
element = newElement;
}
}
通过引用获取元素并重新分配。但是这样做
foreach(集合中的ref var元素)
$ p $ C>中的p>
无法编译,而且我不确定如果编译后它是否还能执行我想要的操作。如何访问集合中的物理引用以对其进行修改?
我的方法签名是否有帮助:
public static void ReplaceReference< T>(
ICollection< T集合,
T newReference,
Func< T,bool>谓词)
编辑:
由于不清楚,我不能只需将
ICollection< T>
更改为其他名称即可。我得到一个ICollection
-这就是我所知道的,我无法更改。无论我多么希望自己成为IList
或IEasilyReplacable
的人,我都不能对此造成影响。 / p>
解决方案所以我把头撞在墙上,想出了一个非常简单的解决特定替换问题的方法,那就是找到,删除并添加。
var existing = collection.FirstOrDefault(predicate);
if(existing!= null)
{
collection.Remove(existing);
collection.Add(newReference);
}
但是,我认为这是解决我的
foreach
问题,因此已将此问题作为后续发布:通过引用在foreach中从集合中获取的抓取元素
编辑:
对于丹尼尔·怀特(Daniel A. White)的评论:
我只打算处理第一个,但是可以很容易地更改为替换-全部:
var现有=集合。
foreach(现有的var元素)
{
collection.Remove(element);
}
for(int i = 0; i{
collection.Add(newReference);
}
关于订购-
ICollection
不一定是有序的。因此,解决该问题的方法将是创建一个具有较少通用签名的新方法静态void ReplaceReference< T>(
IList< T>列表,
T newReference,
Func< T,bool>谓词)
将使用索引器替换值
for(int i = 0; i< list .Count; ++ i)
{
if(predicate(list [i]))
{
list [i] = newReference;
//如果替换为一个变体,则在此处中断。
}
}
现在在main方法中,我们检查是否收集了是IList,因此是有序的,并将其传递给有序版本:
if(集合为IList< T>列表) b $ b {
ReplaceReference(list,newReference,predicate);
的回报;
}
================ ================================================== ========
边注:当然也有dumbo方法:
var newCollection = new List< T>();
foreach(集合中的var元素)
{
newList.Add(predicate(element)?newReference:element);
}
collection.Clear();
foreach(newCollection中的newElement)
{
collection.Add(newElement);
}
但是效率很低。
The thing I wanna do would appear really simple - I want to find an element in an
ICollection<T>
that satisfies a given predicate and replace it with another. In C++ I would write this like:for(auto &element : collection) { if(predicate(elem)) { element = newElement; } }
Grab the element by reference and reassign it. However doing
foreach(ref var element in collection)
in C# fails to compile, and I'm unsure if it'd even do what I want if it did compile. How do I access the physical reference within a collection to modify it?
My method signature if it helps:
public static void ReplaceReference<T>( ICollection<T> collection, T newReference, Func<T, bool> predicate)
EDIT:
Since it appears unclear, I cannot just take the
ICollection<T>
and change it to something else. I'm getting anICollection
- that's all I know and I can't change that. No matter how much I'd love this to be anIList
, orIEasilyReplacable
I can't influence that.解决方案So I bashed my head against the wall and came up with a really simple solution for the particular replace problem, which is to find, remove and then add.
var existing = collection.FirstOrDefault(predicate); if (existing != null) { collection.Remove(existing); collection.Add(newReference); }
However, I see it as rather a workaround to my
foreach
issue, and have thus posted this question as a follow-up: Grab element from a Collection by reference in a foreachEDIT:
For Daniel A. White's comment:
Handling only the first one was what I intended to do, but it can be easily changed to replace-all:
var existing = collection.Where(predicate); foreach(var element in existing) { collection.Remove(element); } for(int i = 0; i < existing.Count); ++i) { collection.Add(newReference); }
As for ordering -
ICollection
is not necessarily ordered. So the way for fixing that would be creating a new method with a less general signaturestatic void ReplaceReference<T>( IList<T> list, T newReference, Func<T, bool> predicate)
that would use the indexer to replace the values
for(int i = 0; i < list.Count; ++i) { if(predicate(list[i])) { list[i] = newReference; // break here if replace-one variant. } }
And now in the main method we check if our collection is an IList, therefore ordered, and pass it to the ordered version:
if(collection is IList<T> list) { ReplaceReference(list, newReference, predicate); return; }
===========================================================================
Sidenote: of course there is also the dumbo approach:
var newCollection = new List<T>(); foreach(var element in collection) { newList.Add(predicate(element) ? newReference : element); } collection.Clear(); foreach(var newElement in newCollection) { collection.Add(newElement); }
but it's highly inefficient.
这篇关于如何替换集合中的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!