根据配对值

时间:2015-06-29 18:20:22

标签: c++ sorting dictionary boost vector

我的地图定义如下:

std::map<std::string, std::vector<std::pair<std::string, std::string>>> groupList;

目标:
我有一组命令列表。我想按顺序排列每个组。为此,每个组都有一个“序列”值。我想基于从最小到最大的这个值对整个列表进行排序。基本上,我有一个元素列表,每个元素都有一个伴随的列表,其中包含特定于每个父元素的其他值。我想按子列表中的特定对或值对父项列表进行排序。

让我想象一下,我用PHP创建了一个类似结构的数组。我不确定如何可视化C ++地图,所以这只是我做出的假设。 1,2,3是地图的关键。

Array
(
    [1] => Array
        (
            [groupID] => 1
            [sequence] => 0
            [command] => DefaultState
        )

    [2] => Array
        (
            [groupID] => 2
            [sequence] => 2
            [command] => Restart
        )

    [3] => Array
        (
            [groupID] => 3
            [sequence] => 1
            [command] => Beep
        )

)

我想根据内部特定对的值对此地图进行排序,在本例中为“序列”。使用“序列”值排序时,元素“2”应低于元素“3”。 最终结果如下:

Array
(
    [1] => Array
        (
            [groupID] => 1
            [sequence] => 0
            [command] => DefaultState
        )

    [3] => Array
        (
            [groupID] => 3
            [sequence] => 1
            [command] => Beep
        )

    [2] => Array
        (
            [groupID] => 2
            [sequence] => 2
            [command] => Restart
        )

)

我很抱歉在这里混合语言,但我没有简单的方法来转储描绘其结构的地图(我知道)。 起初,我的地图设置如下:

std::map<std::string, std::map<std::string, std::string>> groupList;

这对我来说更容易添加元素然后再访问它们,但我认为矢量对更容易用于排序。我宁愿使用后一种定义来轻松。我正在考虑使用std::sortboost,但我没有为这个特定情况实施运气。

欢迎任何评论/帮助。谢谢!

2 个答案:

答案 0 :(得分:4)

每当我看到数据结构时,我想有一个方便的定义:

struct Item {
    int groupID;
    int sequence;
    std::string command;
}

现在您可以轻松定义数组:

Item arr[] = {
    { 1, 0, "DefaultState" },
    { 2, 2, "Restart"      },
    { 3, 1, "Beep"         },
};

由于它是一个带有值语义的简单聚合,您只需定义一个订单并对其进行排序:

struct Item {
    int groupID;
    int sequence;
    std::string command;

    bool operator<(Item const& other) const {
         return sequence < other.sequence;
    }
};

演示

添加流媒体运营商&lt;&lt;我们得到了一个完整的演示版:

<强> Live On Coliru

#include <iostream>

struct Item {
    int groupID;
    int sequence;
    std::string command;

    bool operator<(Item const& other) const {
        return sequence < other.sequence;
    }

    friend std::ostream& operator<<(std::ostream& os, Item const& i) {
        return os << "Item { group:" << i.groupID << ", sequence:" << i.sequence << ", command:'" << i.command << "' }";
    }
};

#include <algorithm>
int main() {
    Item arr[] = {
        { 1, 0, "DefaultState" },
        { 2, 2, "Restart"      },
        { 3, 1, "Beep"         },
    };

    std::sort(std::begin(arr), std::end(arr));

    for (auto& item : arr)
        std::cout << item << '\n';
}

打印

Item { group:1, sequence:0, command:'DefaultState' }
Item { group:3, sequence:1, command:'Beep' }
Item { group:2, sequence:2, command:'Restart' }

答案 1 :(得分:1)

扩展my earlier answer,如果您真的想要更高级的东西,请使用Boost MultiIndex容器来解释一下:

<强> Live On Coliru

#include <fstream>
#include <iostream>

struct Item {
    int groupID;
    int sequence;
    std::string command;

    friend std::ostream& operator<<(std::ostream& os, Item const& i) {
        return os << "Item { group:" << i.groupID << ", sequence:" << i.sequence << ", command:'" << i.command << "' }";
    }
};

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/member.hpp>

namespace bmi = boost::multi_index;
using Table = bmi::multi_index_container<
        Item,
        bmi::indexed_by<
            bmi::ordered_unique<
                bmi::tag<struct by_group>,
                bmi::member<Item, int, &Item::groupID>
            >,
            bmi::ordered_unique<
                bmi::tag<struct by_sequence>,
                bmi::member<Item, int, &Item::sequence>
            >
        >
    >;

#include <algorithm>
#include <map>

int main() {
    Table arr = {
        { 1, 0, "DefaultState" },
        { 2, 2, "Restart"      },
        { 3, 1, "Beep"         },
    };

    for (auto& item : arr.get<by_group>())
        std::cout << item << '\n';

    std::cout << "\nsorted by sequence:\n";
    for (auto& item : arr.get<by_sequence>())
        std::cout << item << '\n';
}

打印

Item { group:1, sequence:0, command:'DefaultState' }
Item { group:2, sequence:2, command:'Restart' }
Item { group:3, sequence:1, command:'Beep' }

sorted by sequence:
Item { group:1, sequence:0, command:'DefaultState' }
Item { group:3, sequence:1, command:'Beep' }
Item { group:2, sequence:2, command:'Restart' }