【问题标题】:Container ordering requirements (in an effort to understand boost::multi_index)容器订购要求(为了理解 boost::multi_index)
【发布时间】:2016-10-06 20:42:18
【问题描述】:

给定一组建模为:

struct Foo { int id; std::string name; };

其中id 是唯一的,name 是非唯一/非{null|empty}。

如何使用 boost::multi_index 之类的数据结构,它可以让我执行以下操作:

select id, name from Foo group by name order by id

标准的 STL 容器无法将我带到应许之地。我使用上面的 sql 变体只是为了表达我的观点。我并没有真正处理任何数据库。

更新:

所以,显然我只需要:

typedef boost::multi_index_container<
  Foo,
  indexed_by<
    ordered_unique<identity<Foo>>,
    ordered_unique<member<Foo, std::string, &Foo::name>>
  >
> MIC;

有人可以确认我做对了吗?它似乎工作。我还没有测试过。

【问题讨论】:

  • @Treycos 它根本不是重复的。请再次查看我的 sql 查询。我没有要求按 id 排序,然后按名称排序。我说我想按 id 排序,同时将所有 相同 名称分组并在其中分配 any id。所以 {1, "Foo"} {2, "Bar" } {3, "Foo"} 最终会返回 {1, "Foo"} {2, "Bar"} OR {2, "酒吧"} {3, "Foo"}
  • 比我更有魔力的人可以删除“这个问题可能已经有答案”的标签吗?它看起来不适合我的情况。

标签: c++ stl boost-multi-index


【解决方案1】:

在使用boost方面,我用的不多,但我认为这里没有必要,这取决于你需要这个操作有多高效。

如果您有 Foo 的标准库容器,为了简单起见,假设为 std::vector&lt;Foo&gt;。您可以执行以下操作:

std::string nameToSearchFor( "Bar" );
std::vector<Foo> vecFoos;
std::vector<Foo> results;
auto it = std::find_if( it, vecFoos.cend(), [&]( const Foo& foo ) {
   return (foo.name == nameToSearchFor);
});

while (it != vecFoos.cend())
{
   results.emplace_back( *it );

   it = std::find_if( it, vecFoos.cend(), [&]( const Foo& foo ) {
       return (foo.name == nameToSearchFor);
   });
}

std::sort( results.begin(), results.end(), []( const Foo& lhs, const Foo& rhs ) {
    return lhs.id < rhs.id;
});

这将适用于任何 STL 容器,或任何至少提供对其元素的 ForwardIterator 访问的容器。但是,如果您使用像 std::unordered_multimap 这样的东西,您将希望利用其内部的 find/equal_range 方法。

有很多方法可以加快速度,但这是一种天真、快速且易于理解的方法,可以满足您的需求,并且适用于小型数据集。

【讨论】:

  • 谢谢!我知道如何以艰难的方式做到这一点。 boost::multi_index 似乎是为此目的量身定制的,我想看看如何免费获得这些东西。我拍了一张,如果你看到我更新的帖子,它似乎有效。我没有用更多的输入对它进行广泛的测试。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-23
  • 2011-03-29
  • 1970-01-01
  • 2017-01-27
  • 1970-01-01
相关资源
最近更新 更多