我有一个名为struct
的简单Item
。
struct Item {
unsigned int id;
std::string name;
Item() : id( 0 ), name( std::string( "" ) ) {
};
};
然后我让这个班级来容纳所有这些Item
。
class ItemData {
public:
std::vector< Item > m_Items;
private:
void load() {
// Parse a JSON string to fill up m_Items vector with
// Item objects.
}
const Item getItem( unsigned int pID ) {
// Create an "empty" Item object with ID = 0 and name = ""
Item temp = Item();
// Loop through the vector
for ( unsigned int i = 0; i < m_Items.size(); i++ ) {
// Check if the current Item object has the id we are looking for
if ( m_Items.at( i ).id == pID ) {
// The item is inside the vector, replace temp with the
// target vector
temp = m_Items.at( i );
// Stop looping
break;
}
}
// If pID was found, temp will have the values of the object inside the vector
// If not, temp will have id = 0 and name = ""
return temp;
}
};
我觉得这个方法需要花费太多时间,特别是如果在循环中调用了ItemData::getItem(unsigned int)
。
是否有更有效的方法在矢量中获取对象而不通过矢量循环?我应该使用不同的容器(例如std::list
)吗?
答案 0 :(得分:4)
改为使用std::map
:
class ItemData {
public:
std::map<unsigned, Item> m_Items;
private:
void load() {
// Parse a JSON string to fill up m_Items vector with
// Item objects.
}
const Item getItem(unsigned id) const {
std::map<unsigned, Item>::const_iterator it = m_Items.find(id);
if (it != m_Items.end())
return it->second;
return Item();
}
};
您也可以考虑std::unordered_map
。
答案 1 :(得分:4)
如果您只想迭代容器中的所有项目,那么矢量就很棒。如果您在相对不频繁的情况下进行线性搜索与性能无关,那么矢量可能仍然可以。
如果您需要能够按ID查找项目并且不关心保留容器中项目的插入顺序,那么请使用map
或unordered_map
取决于您的分拣需求,容器大小等。
如果你需要保持插入顺序和按id 和进行快速查找,你将不会从向量中删除项目,那么我会建议{{ 1)用于索引的id,并在添加新项时保持id-index映射。
答案 2 :(得分:2)
绝对不是std::list
。我相信您正在寻找std::map
(将唯一ID映射到对象)。或者std::set
(只存储唯一对象)和自定义比较器,以便Item
根据id
进行比较。
set
会将对象存储为const
。我相信map
最适合您(将id
存储一次作为地图密钥并且在Item
内部的费用很低)。
答案 3 :(得分:0)
我想保留插入顺序以及快速查找,但可能不需要删除项目
所以你想要的是为矢量做一个索引。这是创建一个哈希表,将项目ID映射到向量中的项目位置:
class ItemData {
vector< Item > m_Items;
unordered_map<unsigned int, size_t> m_ItemsIndex;
void prepare_index()
{
for (size_t i = 0; i < m_Items.size(); i++)
m_ItemsIndex[m_Items[i].id] = i;
}
Item& get_item(unsigned int id)
{
size_t pos = m_ItemsIndex[id];
return m_Items[pos];
}
}
这提高了从线性(O(n))到恒定时间(O(1))的查找速度。
在prepare_index
结束时致电load
。您还需要添加错误检查等,但您明白了。
保留插入顺序,因为您仍然可以直接迭代向量。