- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
如何从 STL 容器中删除具有指定 值或满足某些 条件的元素?
对于不同种类的容器,是否有一种通用或统一的方法?
最佳答案
不幸的是,没有一个单一的uniform 接口(interface)或模式可用于从 STL 容器中删除元素。但出现了三种行为:
从 std::vector
中删除满足特定条件的元素,一种常见的技术是所谓的 erase-remove idiom .
如果 v
是 std::vector
的一个实例, 我们想删除值为 x
的元素从 vector 中,可以使用这样的代码:
// Erase elements having value "x" from vector "v"
v.erase( std::remove(v.begin(), v.end(), x), v.end() );
如果删除元素要满足的标准比简单的“要删除的元素== x”更复杂,std::remove_if()
可以使用算法代替std::remove()
:
// Erase elements matching "erasing_condition" from vector "v"
v.erase( std::remove_if(v.begin(), v.end(), erasing_condition), v.end() );
在哪里 erasing_condition
是一元谓词,可以用多种形式表示:例如它可以是 bool
-返回函数 以 vector 元素类型为输入(所以如果返回值为 true
,该元素将从 vector 中删除;如果是 false
,则不会);或者它可以in-line表示为一个lambda;可以是 functor ;等等
(std::remove()
和 std::remove_if()
都是来自 <algorithm>
header 的通用算法。)
这里有明确的解释from Wikipedia :
The
algorithm
library provides theremove
andremove_if
algorithms for this. Because these algorithms operate on a range of elements denoted by two forward iterators, they have no knowledge of the underlying container or collection. Thus, no elements are actually removed from the container. Rather, all elements which don't fit the remove criteria are brought together to the front of the range, in the same relative order. The remaining elements are left in a valid, but unspecified state. When this is done,remove
returns an iterator pointing one past the last unremoved element.To actually eliminate elements from the container,
remove
is combined with the container'serase
member function, hence the name "erase-remove idiom".
基本上,std::remove()
和 std::remove_if()
将 不 满足删除条件的元素压缩到范围的前面(即 vector
的开头),然后 erase()
实际上从容器中消除了剩余的元素。
这种模式也适用于其他容器,例如 std::deque
。
从 std::list
中删除元素,简单的 remove()
和 remove_if()
方法可用:
// Erase elements having value "x" from list "l"
l.remove( x )
// Erase elements satisfying "erasing_condition" from list "l"
l.remove_if( erasing_condition );
(其中 erasing_condition
是一元谓词,与上一节中讨论的 std::remove_if()
具有相同的特征。)
相同的模式可以应用于类似的容器,例如 std::forward_list
。
关联容器,例如 std::map
, std::set
, std::unordered_map
等遵循此处描述的常见模式:
如果删除条件是简单的键匹配(即“删除元素有键 x"),然后可以调用一个简单的 erase()
方法:
// Erase element having key "k" from map "m":
m.erase( k );
如果删除条件比较复杂,用一些习惯来表示一元谓词(例如“删除所有奇数元素”),然后是 for
可以使用循环(在循环体中检查明确的删除条件,并调用 erase(iterator)
方法):
//
// Erase all elements from associative container "c", satisfying "erasing_condition":
//
for (auto it = c.begin(); it != c.end(); /* "it" updated inside loop body */ )
{
if ( erasing_condition(*it) )
{
// Erase the element matching the specified condition
// from the associative container.
it = c.erase(it);
// Note:
// erase() returns an iterator to the element
// that follows the last element removed,
// so we can continue the "for" loop iteration from that position.
}
else
{
// Current element does _not_ satisfy erasing condition,
// so we can just move on to the next element.
++it;
}
}
从上述分析中可以看出,遗憾的是,从 STL 容器中删除元素并没有统一的通用方法。
下表总结了上述模式:
----------------+------------------------------------------
Container | Erasing Pattern
----------------+------------------------------------------
|
vector | Use erase-remove idiom.
deque |
|
----------------+------------------------------------------
|
list | Call remove()/remove_if() methods.
forward_list |
|
----------------+------------------------------------------
|
map | Simple erase(key) method call,
set | or
unordered_map | loop through the container,
multimap | and call erase(iterator) on matching
| condition.
... |
|
----------------+------------------------------------------
根据特定容器编写不同的特定代码容易出错、难以维护、难以阅读等。
但是,可以为不同的容器类型编写具有通用名称(例如 erase()
和 erase_if()
)重载的函数模板,并将上述模式实现嵌入到这些函数中。
因此,客户可以简单地调用那些 erase()
和 erase_if()
泛型函数,编译器将根据容器类型将调用分派(dispatch)给正确的实现(在编译时)。
介绍了一种更优雅的方法,使用模板元编程技术by Stephan T. Lavavej here .
关于c++ - 如何从 STL 容器中删除元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16013545/
这是我想做的 1 - 点击提交 2 - 隐藏 DIV 容器 1 3 - 显示 DIV 容器 2 4 - 将“PricingDisclaimer.php”中找到的所有 DIV 加载到 Div 容器 2
我有一个 ios 应用程序,它使用 iCloudcontainer 来保存用户的一些数据,例如用户的“到期日期”。我要用不同的方式创建应用程序的副本开发者账号。我要将用户从第一个应用程序迁移到第二个应
这是场景。 我有三个容器。 Container1、container2 和 container3(基于 Ubuntu 的镜像),其中 container2 充当容器 1 和容器 2 之间的路由器。 我
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 9 年前。 Improve this ques
我正在改造管道以使用声明式管道方法,以便我能够 to use Docker images在每个阶段。 目前我有以下工作代码,它执行连接到在 Docker 容器中运行的数据库的集成测试。 node {
我正在开发一个需要尽可能简单地为最终用户安装的应用程序。虽然最终用户可能是经验丰富的 Linux 用户(或销售工程师),但他们对 Tomcat、Jetty 等并不真正了解,我认为他们也不应该了解。 所
我从gvisor-containerd-shim(Shim V1)移到了containerd-shim-runsc-v1(Shim V2)。在使用gvisor-containerd-shim的情况下,
假设我们只在某些开发阶段很少需要这样做(冒烟测试几个 api 调用),让项目 Bar 中的 dockerized web 服务访问 Project Foo 中的 dockerized web 服务的最
各位,我的操作系统是 Windows 10,运行的是 Docker 版本 17.06.0-ce-win19。我在 Windows 容器中运行 SQL Server Express,并且希望将 SQL
谁能告诉我,为什么我们不能在 Azure 存储中的容器内创建容器?还有什么方法可以处理,我们需要在 azure 存储中创建目录层次结构? 最佳答案 您无法在容器中创建容器,因为 Windows Azu
#include template struct Row { Row() { puts("Row default"); } Row(const Row& other) { puts
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
RDF容器用于描述一组事物 例如,把一本书的所有作者列在一起 RDF容器有三种类型: <Bag> <Seq> <Alt> <rdf:
编辑:从到目前为止添加的答案和评论看来,我没有正确解释我想要什么。下面是一个例子: // type not supporting any type of comparison [] [] type b
我正在测试 spatie 的异步项目。我创建了一个这样的任务。 use Spatie\Async\Task; class ServiceTask extends Task { protecte
我想使用 Azure Blob 存储来上传和下载文档。有一些公司可以上传和下载他们的文档。我想保证这些文件的安全。这意味着公司只能看到他们的文件。不是别人的。 我可以在 blob 容器中创建多个文件夹
我正在尝试与 Azure 中的容器实例进行远程交互。我已执行以下步骤: 已在本地注册表中加载本地镜像 docker load -i ima.tar 登录远程 ACR docker登录--用户名--密码
我正在研究http://progrium.viewdocs.io/dokku/process-management/,并试图弄清楚如何从单个项目中运行多个服务。 我有一个Dockerfile的仓库:
我有一个想要容器化的单体应用程序。文件夹结构是这样的: --app | |-file.py <-has a variable foo that is passed in --configs
我正在学习 Docker,并且一直在为 Ubuntu 容器制作 Dockerfile。 我的问题是我不断获取不同容器之间的持久信息。我已经退出,移除了容器,然后移除了它的图像。在对 Dockerfil
我是一名优秀的程序员,十分优秀!