【问题标题】:How can I find an object in a vector based on class properties?如何根据类属性在向量中找到对象?
【发布时间】:2013-02-25 09:00:46
【问题描述】:

我有一个类Attribute,属性为std::string attributeName。我想开发一个简单的函数,它返回Attribute 的索引,该索引具有与提供的字符串匹配的attributeName。不幸的限制包括:我没有 c++0x 可供使用,而且我已经为更复杂的事情重载了 Attribute == 运算符。任何帮助将不胜感激,谢谢!

edit- 非常抱歉,我意识到我正在搜索的属性向量尚不清楚。vector<Attribute> aVec

【问题讨论】:

  • 不能通过 getter 访问名称吗?
  • 可以有多个对象具有相同的属性值吗?你想要一组结果,还是第一个匹配?向量可以重新排序吗?性能重要吗?

标签: c++ vector find


【解决方案1】:

std::find_if 与自定义function object 一起使用:

class FindAttribute
{
    std::string name_;

public:
    FindAttribute(const std::string& name)
        : name_(name)
        {}

    bool operator()(const Attribute& attr)
        { return attr.attributeName == name_; }
};

// ...

std::vector<Attribute> attributes;
std::vector<Attribute>::iterator attr_iter =
    std::find_if(attributes.begin(), attributes.end(),
        FindAttribute("someAttrName"));
if (attr_iter != attributes.end())
{
    // Found the attribute named "someAttrName"
}

要在 C++11 中做到这一点,实际上并没有什么不同,只是你显然不需要函数对象,或者必须声明迭代器类型:

std::vector<Attribute> attributes;

// ...

auto attr_iter = std::find_if(std::begin(attributes), std::end(attributes),
    [](const Attribute& attr) -> bool
    { return attr.attributeName == "someAttrName"; });

或者,如果您需要使用不同的名称多次执行此操作,请将 lambda 函数创建为变量,并在对 std::find_if 的调用中使用 std::bind

auto attributeFinder =
    [](const Attribute& attr, const std::string& name) -> bool
    { return attr.attributeName == name; };

// ...

using namespace std::placeholders;  // For `_1` below

auto attr_iter = std::find_if(std::begin(attributes), std::end(attributes),
    std::bind(attributeFinder, _1, "someAttrName"));

【讨论】:

  • 您能否在现代 C++ 中为未来提供答案?
【解决方案2】:

您可以简单地使用 for 循环来达到此目的:

for (int i = 0; i<aVec.size();i++)
{
    if(aVec[i].attributeName == "yourDesiredString")
    {
        //"i" is the index of your Vector.      
    }
}

【讨论】:

    【解决方案3】:

    您也可以使用 boost 库中的绑定函数:

    std::vector<Attribute>::iterator it = std::find_if(
         aVec.begin(),
         aVec.end(),
         boost::bind(&Attribute::attributeName, _1) == "someValue"
    );
    

    或 C++11 绑定函数:

    std::vector<Attribute>::iterator it = std::find_if(
        aVec.begin(),
        aVec.end(),
        std::bind(
            std::equal_to<std::string>(),
            std::bind(&Attribute::attributeName, _1),
            "someValue"
        )
    );
    

    不声明谓词类或函数

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-24
      • 2021-11-03
      • 2019-03-09
      • 2023-04-04
      相关资源
      最近更新 更多