如何通过某个字段将对象插入到map结构中?

发布于 2024-09-17 18:41:38 字数 140 浏览 5 评论 0原文

我有一个对象 - Employee,我想知道如何将该对象插入到按 char* lastName 字段排序的映射结构中。谢谢。 我的地图需要包含指向 Employee 对象而不是对象本身的指针。关键是员工的姓氏,地图需要按员工的姓氏排序,我应该使用multimap吗?

i have an object - Employee, and i want to know how to insert this object to a map structure sorted by char* lastName field. Thanx.
My map need to contain pointers to Employee objects not the objects themselves. the key is the last name of the employee, the map need to be sorted by the employees last name, should i use multimap?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

围归者 2024-09-24 18:41:38

所以你有一个带有自定义比较器函数的 std::map (你已经重载了小于运算符)并且你想要插入对象以便它们处于正确的顺序?

myMap.insert( make_pair( myKey, myEmployee ) );

其中 myKey 是地图的密钥。然而,从你的问题的声音来看,实际上听起来你正在使用该对象作为它自己的密钥。在这种情况下,只需使用 std::set,

mySet.insert( myEmployee );

我还建议您不要使用 char* 作为存储姓氏的方法,而更喜欢使用 std::string。

编辑:

按照下面的注释,您是否必须能够将 const char* 传递到另一个函数中?如果是这样,仍然使用 string 因为它有一个很好的方法 .c_str() 专门用于旧版兼容性。它可以这样使用:

void stuffHappens(const char* _input){
    //magic happens in here
}

stuffHappens( myString.c_str() );

瞧,你更安全了!

So you've got an std::map with a custom comparator function (you've overloaded the less than operator) and you want to insert objects so that they're in the right order?

myMap.insert( make_pair( myKey, myEmployee ) );

where myKey is the key to your map. However, from the sound of your question it actually sounds like you're using the object as it's own key. In that case, just use std::set and

mySet.insert( myEmployee );

I'd also suggest that you not use char* as a means to store lastName and prefer the std::string.

EDIT:

Following the comments down below, are you having to be able to pass in a const char* into another function? If so, still use string as it has a nice method .c_str() specifically for legacy compatibility. It can be used as so:

void stuffHappens(const char* _input){
    //magic happens in here
}

stuffHappens( myString.c_str() );

and voila, you're much safer!

原谅过去的我 2024-09-24 18:41:38

Employee 类定义 bool 运算符 <(const Employee& other)。或者,将 bool 运算符 <(const Employee& left, const Employee& right) 定义为非成员函数,并使其成为 Employee< 的 friend /代码>。第一种方法的优点是它是Employee 的本地方法,并且增强了封装性。后一种方法的优点是它适用于可转换为 Employee 的任意两种类型。或者,您可以创建一个比较函子,而不是运算符 <(),并将其传递给映射的构造函数。

最后,使用 std::mapinsert() 成员函数插入新员工。 std::map<> 还定义了operator [](),它允许您插入到地图中。如果元素已存在于地图中,则 insert() 函数不会插入该元素,而 operator []() 如果元素已存在,则将更新该元素。

Define bool operator <(const Employee& other) for the Employee class. Alternatively, define bool operator <(const Employee& left, const Employee& right) as a non-member function, and make it a friend of Employee. The advantage of the first approach is that it's local to Employee, and that enhances encapsulation. The advantage of the latter approach is that it will work with any two types that are convertible to Employee. Alternatively, you can create a comparator functor, instead of operator <(), and pass that the map's constructor.

Lastly, use the insert() member function of std::map<> to insert the new employees. std::map<> also has operator []() defined, and it allows you to insert into the map. The insert() function will not insert the element if the element is already in the map, whereas operator []() will update the element if it already exists.

凉城已无爱 2024-09-24 18:41:38

您可以创建一个覆盖 operator() 的“函子”,引用两个对象并返回 obj1 boolean 。 obj2.

例如:

class EmployeeComparator
{
    public:
    bool operator()(const Employee& emp1, const Employee& emp2)
    {
        return strcmp(emp1.lastName, emp2.lastName) < 0;
    }
}

当您创建 std::map 时,您可以将 EmployeeComparator 作为比较对象传递,如下所示:

std::map<Employee, T, EmployeeComparator> m;

其他发帖者重写 < 运算符的想法将起作用也是如此,但是使用这种方法,您可以选择一个标准来排序。按照我的方式,您可以拥有一个按姓氏排序的映射,另一个按员工 ID 排序的映射,等等。对于每个映射,您将传递一个不同的函子作为排序器。

请记住,按照我的方式,如果您尝试按私有字段排序,请将您的排序函子声明为要排序的类的友元类。

You could create a "functor" which overrides operator(), taking references to two of your objects and returning a boolean of obj1 < obj2.

For example:

class EmployeeComparator
{
    public:
    bool operator()(const Employee& emp1, const Employee& emp2)
    {
        return strcmp(emp1.lastName, emp2.lastName) < 0;
    }
}

When you create your std::map, you then pass EmployeeComparator as the comparison object, like so:

std::map<Employee, T, EmployeeComparator> m;

Other posters' ideas of overriding the < operator will work too, but with that method you have pick a single criteria to sort by. With my way, you could have one map that sorts by last name, another that sorts by employee ID, etc. With each map you'd pass a different functor as your sorter.

Keep in mind that with my way, if you are trying to sort by a private field, declare your sorting functor as a friend class of the class to be sorted.

过潦 2024-09-24 18:41:38

正如 Philip Potter 在评论中所写,您应该明确使用 std::string。因为在 cpp 代码中的多个位置/文件中声明的两个不同的 char* 不会 具有相同的地址!由于 char* 只是一个整数,因此您将有多个 char* 键用于一个且只有一个相同的姓氏,这不是您想要的。

走这条路:

std::map<std::string,YourType> yourMap;
std::string strMyLastName = "Rolland";
YourType aValue;
yourMap[strMyLastName ] = aValue;

As Philip Potter has written in comments, you should definetely use std::string. Because two different char* declared at several places/files in your cpp code WON'T have the same addresses ! As a char* is nothing but an integer, you will have several char* keys for one and only one same lastname, and this is not what you want.

go this way:

std::map<std::string,YourType> yourMap;
std::string strMyLastName = "Rolland";
YourType aValue;
yourMap[strMyLastName ] = aValue;
明明#如月 2024-09-24 18:41:38

补充一下wheaties所说的,如果Employee对象包含它自己的键,您可能应该使用set。为了使用该集合,您必须为 Employee 对象显式定义比较方法。有两种方法可以做到这一点,要么定义operator<;对于对象:

class Employee
{
public:
  bool operator<(const Employee &rhs)
  {
    return strcmp(lastName, rhs.lastName) < 0;
  }
...
};

或者您可以定义一个函子,告诉集合用于比较:

struct EmployeeLessThan
{
  bool operator()(const Employee &lhs, const Employee &rhs)
  {
    return strcmp(lhs.lastName, rhs.lastName) < 0;
  }
};

std::set<Employee, EmployeeLessThan> myEmployees;

编辑:要记住的一件非常重要的事情是 set 将其所有项目存储为 常量。这样做是因为对 set 中的元素进行更改可能会更改元素的顺序,而 set 无法检测到这一点并重新排序。如果您想要更新集合中包含的任何员工,这可能会出现问题。解决此问题的最佳方法是将您可能想要更改的 Employee 的任何数据成员声明为可变。即使它们是 const,这也可以让您更改它们的值。

Edit2:如果您决定继续使用地图并且键是 char *,那么请记住,默认情况下地图将比较两个 char *它们的指针的值,而不是它们指向的字符串。在这种情况下,最好的办法是使用 std::string 而不是 char *。或者,您可以定义一个函子来传递给映射:

struct CharStarLessThan
{
  bool operator()(const char *lhs, const char *rhs)
  {
    return strcmp(lhs, rhs) < 0;
  }
};

std::map<char *, Employee, CharStarLessThan> myEmployees;

To add to what wheaties said, if the Employee object contains its own key, you should probably use a set. In order to use the set, you are going to have to explicitly define a method of comparison for the Employee object. There are two ways of doing that, either define operator< for the object:

class Employee
{
public:
  bool operator<(const Employee &rhs)
  {
    return strcmp(lastName, rhs.lastName) < 0;
  }
...
};

Or you can define a functor that you tell the set to use for comparison:

struct EmployeeLessThan
{
  bool operator()(const Employee &lhs, const Employee &rhs)
  {
    return strcmp(lhs.lastName, rhs.lastName) < 0;
  }
};

std::set<Employee, EmployeeLessThan> myEmployees;

Edit: One VERY important thing to keep in mind is that a set stores all of it's items as const. It does this because it's possible that a change to an element in the set could change the order of the elements and set isn't capable of detecting this and reordering. This can be problematic if you want to update any of the employees contained in the set. The best way around this problem is to declare any of the data members of Employee that you might want to change as mutable. This will let you change their values even when it's const.

Edit2: If you decide to continue using a map and the key is a char *, then keep in mind that by default the map is going to compare two char *s by the value of their pointer, not the string they point to. The best thing to do in this case is to use std::string instead of char *. Alternatively, you can define a functor to pass to the map:

struct CharStarLessThan
{
  bool operator()(const char *lhs, const char *rhs)
  {
    return strcmp(lhs, rhs) < 0;
  }
};

std::map<char *, Employee, CharStarLessThan> myEmployees;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文