Esta é uma das maneiras possíveis de sair:
struct RetrieveKey
{
template <typename T>
typename T::first_type operator()(T keyValuePair) const
{
return keyValuePair.first;
}
};
map<int, int> m;
vector<int> keys;
// Retrieve all keys
transform(m.begin(), m.end(), back_inserter(keys), RetrieveKey());
// Dump all keys
copy(keys.begin(), keys.end(), ostream_iterator<int>(cout, "\n"));
Obviamente, também podemos recuperar todos os valores do mapa, definindo outro functor RetrieveValues .
Existe alguma outra maneira de conseguir isso facilmente? (Estou sempre me perguntando por que std :: map não inclui uma função de membro para fazer isso.)
c++
dictionary
stl
stdmap
Owen
fonte
fonte
keys.reserve(m.size());
.Respostas:
Embora sua solução funcione, pode ser difícil de ler, dependendo do nível de habilidade de seus colegas programadores. Além disso, ele afasta a funcionalidade do site de chamada. O que pode dificultar um pouco a manutenção.
Não tenho certeza se o seu objetivo é colocar as chaves em um vetor ou imprimi-las para que eu faça as duas coisas. Você pode tentar algo como isto:
Ou ainda mais simples, se você estiver usando o Boost:
Pessoalmente, gosto da versão BOOST_FOREACH porque há menos digitação e é muito explícito sobre o que está fazendo.
fonte
BOOST_FOREACH
? O código que você propõe aqui está totalmente erradov.reserve(m.size())
evitar o redimensionamento do vetor durante a transferência.fonte
it = ...begin(); it != ...end
. Mais agradável seria, evidentemente, std :: map ter um chaves método () retornando que vector ...answered Mar 13 '12 at 22:33
, que é vários meses após o C ++ 11 se tornar C ++.for(auto const & imap : mapints)
,.Existe um adaptador de faixa de reforço para este fim:
Existe um adaptador de intervalo map_values semelhante para extrair os valores.
fonte
boost::adaptors
não está disponível até o Boost 1.43. A atual versão estável do Debian (Squeeze) oferece apenas o Boost 1.42boost/range/adaptor/map.hpp
O C ++ 0x nos deu uma solução excelente e excelente:
fonte
A resposta de @ DanDan, usando C ++ 11 é:
e usando C ++ 14 (como observado por ivan.ukr), podemos substituir
decltype(map_in)::value_type
porauto
.fonte
keys.reserve(map_in.size());
eficiência.O SGI STL tem um ramal chamado
select1st
. Pena que não está no STL padrão!fonte
Sua solução é boa, mas você pode usar um iterador para fazer isso:
fonte
Baseado na solução @ rusty-parks, mas em c ++ 17:
fonte
std::ignore
possa ser usado em ligações estruturadas dessa maneira. Estou recebendo um erro de compilação. Deve ser suficiente usar apenas uma variável regular, por exemplo,ignored
que simplesmente não seja usada.std::ignore
destina-se ao uso com,std::tie
mas não com ligações estruturais. Eu atualizei meu código.Eu acho que o BOOST_FOREACH apresentado acima é agradável e limpo, no entanto, há outra opção usando o BOOST também.
Pessoalmente, não acho que essa abordagem seja tão limpa quanto a abordagem BOOST_FOREACH nesse caso, mas o boost :: lambda pode ser realmente limpo em outros casos.
fonte
Além disso, se você tiver o Boost, use transform_iterator para evitar fazer uma cópia temporária das chaves.
fonte
Um pouco de uma captura de c ++ 11:
fonte
Você pode usar o versátil boost :: transform_iterator. O transform_iterator permite transformar os valores iterados, por exemplo, no nosso caso, quando você deseja lidar apenas com as chaves, não com os valores. Consulte http://www.boost.org/doc/libs/1_36_0/libs/iterator/doc/transform_iterator.html#example
fonte
Aqui está um bom modelo de função usando magia C ++ 11, trabalhando para std :: map, std :: unordered_map:
Confira aqui: http://ideone.com/lYBzpL
fonte
A melhor solução STL sem sgi e sem boost é estender o map :: iterator da seguinte forma:
e depois use-os assim:
fonte
Com exemplo de mapa atômico
fonte
Um pouco semelhante a um dos exemplos aqui, simplificado da
std::map
perspectiva do uso.Use assim:
fonte
map.size()
significa o dobro do retorno do tamanho do vetor. Por favor, corrija para salvar outra pessoa da dor de cabeça :(Porque ele não pode fazer isso melhor do que você pode fazê-lo. Se a implementação de um método não for superior à implementação de uma função livre, em geral você não deve escrever um método; você deve escrever uma função livre.
Também não está claro imediatamente por que ele é útil.
fonte
empty()
porque pode ser implementado comosize() == 0
.std::map<T,U>
como um contêiner de pares. No Python, adict
age como suas chaves quando iterado, mas permite que vocêd.items()
obtenha o comportamento do C ++. Python também forneced.values()
.std::map<T,U>
certamente poderia fornecer um métodokeys()
evalues()
que retornam um objeto que possuibegin()
eend()
que fornecem iteradores sobre as chaves e valores.