5

考虑以下:

struct A
{
    int i;
    double d;
    std::string s;
};

std::list<A> list_A; 

我想将 list_A 的所有元素复制到地图中,这样地图中的每一对都将包含 list_A 中的一个元素作为值,并将其字符串s作为键。有没有比遍历列表并插入每个元素及其字符串作为映射键更优雅的方法?

4

5 回答 5

6

这应该让您了解如何使用transform

std::pair<std::string, A> pairify(const A& a) { return std::make_pair(a.s, a); }

std::transform(list.begin(), list.end(), std::inserter(map, map.end()), pairify);

使用的原因inserter是:

插入插入器是一种特殊类型的输出迭代器,旨在允许通常覆盖元素(例如复制)的算法在容器中的特定位置自动插入新元素。

于 2013-09-05T20:50:14.467 回答
6

我喜欢标准库算法和 lambda,但它并没有比以下简单得多:

for (const A& value : list_A) {
    map_A.insert(std::make_pair(value.s, value));
}

其他方法正在执行与此代码等效的操作,并且此循环可读且同样快。

于 2013-09-05T21:33:11.533 回答
1

抱歉上次回答太快了,没有详细说明,这里有一个可编译的代码。

struct A
{
    int i;
    double d;
    std::string s;
};

std::list<A> list_A;

std::pair<std::string, A> convert(const A &x) {
    return make_pair(x.s,x);
}

int main() {

    std::map<std::string,A> out;

    std::transform(list_A.begin(), list_A.end(), std::inserter(out,out.end()),convert);

}
于 2013-09-05T20:37:07.337 回答
0

我可以将它存储在set: 中,这样地图(s 本身)中就不会有数据重复:

struct A
{
    bool operator < (const A& r_) const { return (s < r_.s); }
    int i;
    double d;
    std::string s;
};

std::list<A> list_A;
std::set<A> set_A;

for ( std::list<A>::const_iterator itr = list_A.begin(); itr != list_A.end(); ++itr ) {
    if ( ! set_A.insert(*itr).second ) {
      // Handle duplicated elements
    }
}

我可以保持循环:这样你就可以正确处理重复的元素。

于 2013-09-05T21:05:27.693 回答
0

如果您使用 C++11,您可以将 lambda 函数与捕获一起使用:

std::map<std::string, A> m;
std::list<A> l;
std::for_each(l.begin(), l.end(),
              [&](const A& a) {
                  m.insert(std::make_pair(a.s, a));
              });
于 2013-09-05T21:07:28.170 回答