草庐IT

c# - 在迭代列表时从列表中删除/添加项目

coder 2024-05-31 原文

首先,我知道由于显而易见的原因,这是不可能开箱即用的。

foreach(string item in myListOfStrings) {
    myListOfStrings.Remove(item);
}

上面的片段是我见过的最可怕的事情之一。那么,你如何实现它呢?您可以使用 for 向后遍历列表,但我也不喜欢这种解决方案。

我想知道的是:是否有一种方法/扩展可以从当前列表中返回一个 IEnumerable,类似于 float 副本? LINQ 有很多扩展方法可以做到这一点,但您总是必须用它做一些事情,例如过滤(where, take...)。

我期待这样的事情:

foreach(string item in myListOfStrings.Shadow()) {
   myListOfStrings.Remove(item);
}

.Shadow() 在哪里:

public static IEnumerable<T> Shadow<T>(this IEnumerable<T> source) {
    return new IEnumerable<T>(source);
    // or return source.Copy()
    // or return source.TakeAll();
}

示例

foreach(ResponseFlags flag in responseFlagsList.Shadow()) {
    switch(flag) {
        case ResponseFlags.Case1:
            ...
        case ResponseFlags.Case2:
            ...
    }
    ...
    this.InvokeSomeVoidEvent(flag)
    responseFlagsList.Remove(flag);
}

解决方案

我就是这样解决的,效果很好:

public static IEnumerable<T> Shadow<T>(this IEnumerable<T> source) where T: new() {
    foreach(T item in source)
        yield return item;
}

它不是那么快(很明显),但它是安全的并且正是我想要做的。

最佳答案

由于列表的实现方式,从列表中逐一删除多个元素是 C# 反模式。

当然,可以用for循环(而不是foreach)来完成。或者可以通过制作列表的副本来完成。但这就是为什么不应该这样做。在 100000 个随机整数的列表中,这在我的机器上需要 2500 毫秒:

       foreach (var x in listA.ToList())
            if (x % 2 == 0)
                listA.Remove(x);

这需要 1250 毫秒:

        for (int i = 0; i < listA.Count; i++)
            if (listA[i] % 2 == 0)
                listA.RemoveAt(i--);

而这两个分别需要 5 毫秒和 2 毫秒:

        listB = listB.Where(x => x % 2 != 0).ToList();

        listB.RemoveAll(x => x % 2 == 0);

这是因为当你从列表中删除一个元素时,你实际上是从一个数组中删除,这是 O(N) 时间,因为你需要在 之后移动每个元素 删除的元素向左移动一位。平均而言,这将是 N/2 个元素。

Remove(element) 也需要在删除之前找到元素。所以 Remove(element) 实际上总是需要 N 步 - elementindex 步来找到元素,N - elementindex 步来删除它 - 总共 N 步。

RemoveAt(index) 不必找到元素,但它仍然需要移动底层数组,因此平均而言,RemoveAt 是 N/2 步。

无论哪种方式,最终结果都是 O(N^2) 复杂度,因为您要删除多达 N 个元素。

相反,您应该使用 Linq,它将在 O(N) 时间内修改整个列表,或者自己滚动,但您不应该在循环中使用 Remove(或 RemoveAt)。

关于c# - 在迭代列表时从列表中删除/添加项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17233558/

有关c# - 在迭代列表时从列表中删除/添加项目的更多相关文章

  1. ruby - 我需要将 Bundler 本身添加到 Gemfile 中吗? - 2

    当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/

  2. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  3. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  4. ruby - 我可以使用 Ruby 从 CSV 中删除列吗? - 2

    查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html

  5. ruby - 将 Bootstrap Less 添加到 Sinatra - 2

    我有一个ModularSinatra应用程序,我正在尝试将Bootstrap添加到应用程序中。get'/bootstrap/application.css'doless:"bootstrap/bootstrap"end我在views/bootstrap中有所有less文件,包括bootstrap.less。我收到这个错误:Less::ParseErrorat/bootstrap/application.css'reset.less'wasn'tfound.Bootstrap.less的第一行是://CSSReset@import"reset.less";我尝试了所有不同的路径格式,但它

  6. ruby - 续集在添加关联时访问many_to_many连接表 - 2

    我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以

  7. ruby - RVM 使用列表[0] - 2

    是否有类似“RVMuse1”或“RVMuselist[0]”之类的内容而不是键入整个版本号。在任何时候,我们都会看到一个可能包含5个或更多ruby的列表,我们可以轻松地键入一个数字而不是X.X.X。这也有助于rvmgemset。 最佳答案 这在RVM2.0中是可能的=>https://docs.google.com/document/d/1xW9GeEpLOWPcddDg_hOPvK4oeLxJmU3Q5FiCNT7nTAc/edit?usp=sharing-知道链接的任何人都可以发表评论

  8. ruby - 我可以使用 aws-sdk-ruby 在 AWS S3 上使用事务性文件删除/上传吗? - 2

    我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的

  9. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  10. ruby-on-rails - 新 Rails 项目 : 'bundle install' can't install rails in gemfile - 2

    我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="

随机推荐