返回向量中struct结构的索引

时间:2017-01-09 17:15:36

标签: c++ vector struct

我几乎阅读了通过谷歌发现的所有帖子,但它并没有帮助我......

我在一个类中有一个结构:

struct animation {
    int identifier;
    int another_variable;
};

我将一堆这些结构存储在一个向量中:

static std::vector<animation> anims;

现在,我需要根据字段标识符找到结构的索引(位置)。

// This is what I found so far
int Animation::get_animation_index(int identifier) {        
    std::find(anims.begin(), anims.end(), identifier) - anims.begin();
 }

我们的想法是获取向量索引anims [0] .. anims [xxx],其中存储了标识符为xx的结构。

我在循环中尝试了它,但后来我只能访问对象本身,而不是索引..

for (Animation::animation a : anims) {
    if (a.identifier == identifier) {
         // a is now the object, but I need the vector index..

有什么想法吗?

2 个答案:

答案 0 :(得分:9)

for (Animation::animation const& a : anims) {  // note: reference
    if (a.identifier == identifier) {
        return std::addressof(a) - std::addressof(anims[0]);
    }
}

或:

std::find_if(anims.begin(), anims.end(), 
         [ident](const animation& a) { return a.identifier == ident; })
   - anims.begin();

或者,如果动画可能不存在:

int find_index(int ident)
{
    auto it = std::find_if(anims.begin(), anims.end(), 
              [ident](const animation& a) 
              { 
                  return a.identifier == ident; 
              });
    if (it == anims.end())
        return -1; // or throw, depending on requirements
    else 
        return it - anims.begin();
}

最后,如果您的动画按标识符排序,您可以使用二进制搜索,当向量很大时,平均会更快:

int find_index_sorted(const std::vector<animation>& anims, int ident)
{
    struct lower_ident
    {
        constexpr bool operator()(const animation& l, int r) const {
            return l.identifier < r;
        }

        constexpr bool operator()(int l, const animation& r) const {
            return l < r.identifier;
        }
    };
    constexpr auto pred = lower_ident();
    auto it = std::lower_bound(anims.begin(), anims.end(), ident, pred);
    if (it == anims.end() or pred(ident, *it))
        return -1;
    return it - anims.begin();
}

答案 1 :(得分:1)

@RichardHodges find_index的替代方案,它更简单:

for (size_t i = 0; i < anims.size(); ++i)
    if (anims[i].identifier == id)
        return i;