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
中非唯一索引键的独特的计数?以及如何获得Person::name
复合键(Roster
,Person::m_name
)的第一个键(Person::m_id
)的独特计数?谢谢!
编辑:
还是只是一种方法来迭代唯一的第一把 key ?这样我们就可以得到不同数量的第一把 key 。
最佳答案
您可以利用以下事实:您知道复合索引首先是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
);
这可能是一个很好的时间/存储权衡。
演示版
Live On 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