[英]How can I sort a map according to a property of its values?
I've created a map having a vector as below: 我创建了一个具有如下矢量的地图:
map<int,vector<int>> mymap;
How can I sort this map according to the n th value of the vector contained by map? 如何根据地图包含的向量的第 n 个值对该地图排序?
You can't. 你不能 You can provide a custom comparator to make the underlying data get sorted another way than the default, but this only relates to keys , not values .
您可以提供一个自定义比较器,以使基础数据以不同于默认值的另一种方式排序,但这仅与键有关 ,而与值无关。 If you have a requirement for your container's elements to exist in some specific, value-defined order, then you're using the wrong container.
如果您要求容器的元素以某些特定的,按值定义的顺序存在,那么您使用的是错误的容器。
You can switch to a set
, and take advantage of the fact that there is no distinction there between "key" and "value", and hack the underlying sorting yourself: 您可以切换到
set
,并利用“ key”和“ value”之间没有区别的事实,然后自己进行底层排序:
template <std::size_t N>
struct MyComparator
{
typedef std::pair<int, std::vector<int>> value_type;
bool operator()(const value_type& lhs, const value_type& rhs)
{
return lhs.second.at(N) < rhs.second.at(N);
}
};
/**
* A set of (int, int{2,}) pairs, sorted by the 2nd element in
* the 2nd item of each pair.
*/
std::set<std::pair<int, std::vector<int>>, MyComparator<1>> my_data;
int main()
{
my_data.insert(std::make_pair(1, std::vector<int>{0,5,0,0}));
my_data.insert(std::make_pair(2, std::vector<int>{0,2,0,0}));
my_data.insert(std::make_pair(3, std::vector<int>{0,1,0,0}));
my_data.insert(std::make_pair(4, std::vector<int>{0,9,0,0}));
for (const auto& el : my_data)
std::cout << el.first << ' ';
}
// Output: 3 2 1 4
However, if you still need to perform lookup on key as well , then you're really in trouble and need to rethink some things. 然而,如果你仍然需要执行的键查找,以及 ,那么你在你真的遇到麻烦,需要重新考虑一些事情。 You may need to duplicate your data or provide an indexing vector.
您可能需要复制数据或提供索引向量。
If I have understood correctly you can (build) add elements to the map the following way 如果我已正确理解,则可以通过以下方式(构建)向地图添加元素
std::vector<int> v = { 1, 2, 3 };
std::vector<int>::size_type n = 2;
mymap[v[n]] = v;
Here is an example 这是一个例子
#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
#include <cstdlib>
#include <ctime>
int main()
{
std::srand( ( unsigned )time( 0 ) );
const size_t N = 10;
std::map<int, std::vector<int>> m;
for ( size_t i = 0; i < N; i++ )
{
std::vector<int> v( N );
std::generate( v.begin(), v.end(), []{ return std::rand() % N; } );
m[v[0]] = v;
}
for ( auto &p : m )
{
for ( int x : p.second ) std::cout << x << ' ';
std::cout << std::endl;
}
return 0;
}
The output is 输出是
0 1 7 8 1 2 9 0 0 9
1 6 3 1 3 5 0 3 1 5
3 8 0 0 0 7 1 2 9 7
5 9 5 0 7 1 2 0 6 3
6 4 7 5 4 0 0 4 2 0
7 9 8 6 5 5 9 9 4 5
8 3 8 0 5 9 6 6 8 3
9 5 4 7 4 0 3 5 1 9
Take into account that as there can be duplicated vectors (that is that have the same value of the n-th element (in my example n is equal to 0) then some vectors will not be added to the map. If you want to have duplicates then you should use for example std::multimap
请注意,由于可能存在重复的向量(即,第n个元素的值相同(在我的示例中,n等于0),因此某些向量将不会添加到地图中。复制品,那么您应该使用例如
std::multimap
Also you can build a new map according to the criteria based on an existent map. 您还可以根据基于现有地图的条件来构建新地图。
map<int,vector<int>> mymap;
How can i sort this map according to the nth value of the vector contained by map?
如何根据地图包含的向量的第n个值对此地图排序?
That's only possible if you're prepared to use that n th value as the integer key too, as in consistently assigning: 仅当您也准备将第 n 个值用作整数键时,这才有可能,如一致地分配:
mymap[v[n - 1]] = v;
If you're doing that, you might consider a set<vector<int>>
, which removes the redundant storage of that "key" element - you would then need to provide a custom comparison though.... 如果这样做,则可以考虑使用
set<vector<int>>
,它删除了该“键”元素的冗余存储-然后,您需要提供自定义比较。
If you envisage taking an existing populated map that doesn't have that ordering, then sorting its elements - that's totally impossible. 如果您设想采用现有的,没有该顺序的填充地图,然后对其元素进行排序-则完全不可能。 You'll have to copy the elements out to another container, such as a
set
that's ordered on the n th element, or a vector
that you std::sort
after populating. 你必须复制到另一个容器中的元素,如
set
多数民众赞成下令在第n 个元素或vector
,你std::sort
填充后。
You can abuse the fact a c++ map uses a tree sorted by its keys. 您可能会滥用c ++映射使用按其键排序的树的事实。 This means that you can either create a new map, with as keys the values you wish it to be sorted on, but you can also create a
vector
with references to the items in your map, and sort that vector (or the other way around: you could have a sorted vector, and use a map
to create an index on your vector). 这意味着您可以创建一个新的地图,并以您希望对其进行排序的值作为键,但是您也可以创建一个对地图中各项进行引用的
vector
,然后对该矢量进行排序(或者反之:您可以对向量进行排序,并使用map
在向量上创建索引)。 Be sure to use a multimap
in the case of duplicate keys. 请务必使用一个
multimap
在重复键的情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.