按对象属性搜索对象向量

Posted

技术标签:

【中文标题】按对象属性搜索对象向量【英文标题】:Search a vector of objects by object attribute 【发布时间】:2022-01-24 01:57:32 【问题描述】:

我正在尝试找出一种很好的方法来查找向量中某个对象的索引 - 通过将字符串与对象中的成员字段进行比较。

像这样:

find(vector.begin(), vector.end(), [object where obj.getName() == myString])

我已经搜索但没有成功 - 也许我不完全了解要查找的内容。

【问题讨论】:

可以有多个同名对象吗?您想找到所有这些吗? 如何在两个对象容器中搜索匹配的成员变量? 【参考方案1】:

您可以将std::find_if 与合适的函子一起使用。在此示例中,使用了 C++11 lambda:

std::vector<Type> v = ....;
std::string myString = ....;
auto it = find_if(v.begin(), v.end(), [&myString](const Type& obj) return obj.getName() == myString;)

if (it != v.end())

  // found element. it is an iterator to the first matching element.
  // if you really need the index, you can also get it:
  auto index = std::distance(v.begin(), it);

如果您没有 C++11 lambda 支持,则函子可以工作:

struct MatchString

 MatchString(const std::string& s) : s_(s) 
 bool operator()(const Type& obj) const
 
   return obj.getName() == s_;
 
 private:
   const std::string& s_;
;

这里,MatchString 是一种类型,其实例可以使用单个 Type 对象调用,并返回一个布尔值。例如,

Type t("Foo"); // assume this means t.getName() is "Foo"
MatchString m("Foo");
bool b = m(t); // b is true

然后您可以将实例传递给std::find

std::vector<Type>::iterator it = find_if(v.begin(), v.end(), MatchString(myString));

【讨论】:

如果您使用的是仿函数,则需要使用find_if 如何在两个对象容器中搜索匹配的成员变量?【参考方案2】:

除了 Lambda 和 juancho 使用的手写函子之外,您还可以使用 boost::bind (C++03) 或 std::bind (C++11) 和一个简单的函数:

bool isNameOfObj(const std::string& s, const Type& obj)
 return obj.getName() == s; 

//...
std::vector<Type>::iterator it = find_if(v.begin(), v.end(), 
  boost::bind(&isNameOfObj, myString, boost::placeholders::_1));

或者,如果Type 有一个方法isName

std::vector<Type>::iterator it = find_if(v.begin(), v.end(), 
  boost::bind(&Type::isName, boost::placeholders::_1, myString));

这只是为了完整性。在 C++11 中,我更喜欢 Lambda,在 C++03 中,只有当比较函数本身已经存在时,我才会使用 bind。如果不是,请选择仿函数。

PS: 由于 C++11 没有多态/模板化 lambda,因此 bind 在 C++11 中仍然占有一席之地,例如如果参数类型未知、难以拼写或难以推断。

【讨论】:

【参考方案3】:

一个简单的迭代器可能会有所帮助。

typedef std::vector<MyDataType> MyDataTypeList;
// MyDataType findIt should have been defined and assigned 
MyDataTypeList m_MyObjects;
//By this time, the push_back() calls should have happened
MyDataTypeList::iterator itr = m_MyObjects.begin();
while (itr != m_MyObjects.end())

  if(m_MyObjects[*itr] == findIt) // any other comparator you may want to use
    // do what ever you like

【讨论】:

在while循环中不应该有++itr吗?

以上是关于按对象属性搜索对象向量的主要内容,如果未能解决你的问题,请参考以下文章

如何使用二分搜索将元素插入已排序的向量中

基础向量空间搜索引擎理论

Mongoose 按对象搜索数据

通过搜索嵌套对象属性过滤对象数组

在对象的 NSArray 中搜索与任何属性匹配的字符串

在对象列表中搜索对象属性android