如何替换集合中的元素 [英] How to replace an element in a Collection

查看:684
本文介绍了如何替换集合中的元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想做的事情看起来非常简单-我想在 ICollection< T> 中找到一个满足给定谓词的元素,然后将其替换为另一个。在C ++中,我会这样写:

  for(auto& element:collection){

if(predicate(elem)){
element = newElement;
}
}

通过引用获取元素并重新分配。但是这样做

  foreach(集合中的ref var元素)
中的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 an ICollection - that's all I know and I can't change that. No matter how much I'd love this to be an IList, or IEasilyReplacable 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 foreach

EDIT:

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 signature

static 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆