如何使用组合键获取boost::multi_index_container中第一个键的不同计数
How to get the distinct count of first key in boost::multi_index_container with composite key
boost::multi_index_container
支持构建容器,维护一个或多个具有不同排序和访问语义的索引,如关系数据库。我使用boost::multi_index_container
和复合密钥来处理这样的事情:
struct Person {
Person(int id, string name):
m_id(id),
m_name(name)
{
}
int m_id;
string m_name;
};
typedef multi_index_container<
Person,
indexed_by<
ordered_unique<
member<Person, int, &Person::m_id>
>,
ordered_unique<
composite_key<
Person,
member<Person, string, &Person::m_name>,
member<Person, int, &Person::m_id>
>
>
>
> Roster;
int main()
{
Roster r;
r.insert(Person(1, "Tom"));
r.insert(Person(2, "Jack"));
r.insert(Person(3, "Tom"));
r.insert(Person(4, "Leo"));
/* The distinct count of name must be 3, and how to get it? */
}
在类似boost::multi_index_container
的关系数据库中,有任何方法可以获得非唯一索引键的不同计数吗?以及如何获得Roster
复合密钥(Person::m_name
,Person::m_id
)的第一个密钥(Person::name
)的不同计数?THX!
编辑:或者这是一种只迭代不同的第一个键的方法?这样我们就可以得到第一个键的不同计数。
您可以利用这样一个事实,即您知道复合索引是按m_name
排序的。
这意味着你可以在没有额外排序步骤的情况下运行一个标准的"唯一":
size_t unique_names = boost::size(r.get<by_name_id>()
| transformed([](Person const& p) -> std::string const& { return p.m_name; })
| uniqued
);
这可能是一个很好的时间/存储权衡。
Demo
在Coliru上直播
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/composite_key.hpp>
struct Person {
Person(int id, std::string name):
m_id(id),
m_name(name)
{
}
int m_id;
std::string m_name;
};
namespace bmi = boost::multi_index;
typedef boost::multi_index_container<
Person,
bmi::indexed_by<
bmi::ordered_unique<
bmi::member<Person, int, &Person::m_id>
>,
bmi::ordered_unique<
bmi::tag<struct by_name_id>,
bmi::composite_key<
Person,
bmi::member<Person, std::string, &Person::m_name>,
bmi::member<Person, int, &Person::m_id>
>
>
>
> Roster;
#include <iostream>
#include <boost/range/algorithm.hpp>
#include <boost/range/adaptors.hpp>
using boost::adaptors::transformed;
using boost::adaptors::uniqued;
int main()
{
Roster r;
r.insert(Person(1, "Tom"));
r.insert(Person(2, "Jack"));
r.insert(Person(3, "Tom"));
r.insert(Person(4, "Leo"));
size_t unique_names = boost::size(r.get<by_name_id>()
| transformed([](Person const& p) -> std::string const& { return p.m_name; })
| uniqued
);
std::cout << unique_names;
}
打印
3
另一种可能的方法,如果有许多元素具有相同的键,可能会更快,包括使用upper_bound
:跳过索引
在Coliru上直播
template<typename Index,typename KeyExtractor>
std::size_t distinct(const Index& i,KeyExtractor key)
{
std::size_t res=0;
for(auto it=i.begin(),it_end=i.end();it!=it_end;){
++res;
it=i.upper_bound(key(*it));
}
return res;
}
int main()
{
Roster r;
r.insert(Person(1, "Tom"));
r.insert(Person(2, "Jack"));
r.insert(Person(3, "Tom"));
r.insert(Person(4, "Leo"));
auto d=distinct(r.get<1>(),[](const Person& p){return std::cref(p.m_name);});
std::cout<<d<<"n";
}
相关文章:
- 为什么它只打印双链接列表的第一个值,而我的程序却崩溃了
- std::find,返回所有找到的值的替代方法,而不仅仅是存在重复的向量的第一个值
- 如何仅读取文本文件中的第一个值
- 在C++中,如何在第一个"system()"结束后执行第二个"system()"?
- 查找不在标准中的第一个值::设置<int>最小-最大值
- C++:忽略第一个 cin.ignore 之后的输入
- 在C++中打印多个矢量的第一个值
- C++去除前x个元素的有效方法,在不改变向量大小的情况下将第x+1个元素推到第一个
- C++第一个cout将不会打印
- 我们可以在第一个else-if条件结束后使用另一个else-if条件吗
- OpenGL:第二个VBO破坏了第一个VBO
- 为什么第一个Dynamic_cast没有投射到基类?
- OpenGL 2D游戏只绘制第二个精灵纹理而不是第一个
- C++ 为什么程序只读取第一个值
- 在我的第一个C++程序中需要一些帮助(简单)
- 为什么我的代码在第一个 if 语句处中断?
- 是否可以从另一个类对象调用一个类函数而不继承第一个类
- 无法使我的第一个Windows OpenGL窗口抬起并运行
- 将参数初始化为构造函数,而不是第一个
- 无法在硬件模式下创建 SGX 安全区 - "invalid launch token"即使文档将无效的启动令牌指定为第一个