Ini adalah salah satu cara yang mungkin saya lakukan:
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"));
Tentu saja, kita juga dapat mengambil semua nilai dari peta dengan mendefinisikan functor lain RetrieveValues .
Apakah ada cara lain untuk mencapai ini dengan mudah? (Saya selalu bertanya-tanya mengapa std :: map tidak menyertakan fungsi anggota untuk kita lakukan.)
c++
dictionary
stl
stdmap
Owen
sumber
sumber
keys.reserve(m.size());
.Jawaban:
Walaupun solusi Anda harusnya berhasil, bisa jadi sulit untuk membaca tergantung pada tingkat keterampilan rekan programmer Anda. Selain itu, ini memindahkan fungsionalitas dari situs panggilan. Yang bisa membuat perawatan sedikit lebih sulit.
Saya tidak yakin apakah tujuan Anda adalah memasukkan kunci ke vektor atau mencetaknya ke cout, jadi saya melakukan keduanya. Anda dapat mencoba sesuatu seperti ini:
Atau bahkan lebih sederhana, jika Anda menggunakan Boost:
Secara pribadi, saya suka versi BOOST_FOREACH karena mengetik kurang dan sangat eksplisit tentang apa yang dilakukannya.
sumber
BOOST_FOREACH
? Kode yang Anda usulkan di sini benar-benar salahv.reserve(m.size())
untuk menghindari pengubahan ukuran vektor selama transfer.sumber
it = ...begin(); it != ...end
. Tentu saja yang terbaik adalah std :: map yang memiliki kunci metode () mengembalikan vektor itu ...answered Mar 13 '12 at 22:33
, yaitu beberapa bulan setelah C ++ 11 menjadi C ++.for(auto const & imap : mapints)
,.Ada adaptor jangkauan jelajah untuk tujuan ini:
Ada adaptor rentang map_values serupa untuk mengekstraksi nilai.
sumber
boost::adaptors
tidak tersedia sampai Boost 1.43. Rilis stabil Debian saat ini (Squeeze) hanya menawarkan Boost 1.42boost/range/adaptor/map.hpp
C ++ 0x telah memberi kami solusi lebih lanjut, sangat baik:
sumber
@ Jawaban DanDan, menggunakan C ++ 11 adalah:
dan menggunakan C ++ 14 (seperti dicatat oleh @ ivan.ukr) kita dapat mengganti
decltype(map_in)::value_type
denganauto
.sumber
keys.reserve(map_in.size());
efisiensi.SGI STL memiliki ekstensi yang disebut
select1st
. Sayang sekali tidak dalam STL standar!sumber
Solusi Anda baik-baik saja tetapi Anda dapat menggunakan iterator untuk melakukannya:
sumber
Berbasis pada solusi @ rusty-taman, tetapi dalam c ++ 17:
sumber
std::ignore
ca dapat digunakan dalam binding terstruktur dengan cara ini. Saya mendapatkan kesalahan kompilasi. Seharusnya cukup dengan hanya menggunakan variabel biasa mis.ignored
Yang tidak digunakan.std::ignore
dimaksudkan untuk digunakan denganstd::tie
tetapi tidak dengan binding struktural. Saya telah memperbarui kode saya.Saya pikir BOOST_FOREACH yang disajikan di atas bagus dan bersih, namun, ada opsi lain menggunakan BOOST juga.
Secara pribadi, saya tidak berpikir pendekatan ini sebersih pendekatan BOOST_FOREACH dalam kasus ini, tetapi boost :: lambda dapat benar-benar bersih dalam kasus lain.
sumber
Juga, jika Anda memiliki Peningkatan, gunakan transform_iterator untuk menghindari membuat salinan kunci sementara.
sumber
Sedikit dari c ++ 11 take:
sumber
Anda dapat menggunakan boost serbaguna :: transform_iterator. Transform_iterator memungkinkan Anda untuk mengubah nilai yang diulang, misalnya dalam kasus kami ketika Anda ingin hanya berurusan dengan kunci, bukan nilai. Lihat http://www.boost.org/doc/libs/1_36_0/libs/iterator/doc/transform_iterator.html#example
sumber
Inilah templat fungsi yang bagus menggunakan C ++ 11 magic, yang bekerja untuk std :: map, std :: unordered_map:
Lihat di sini: http://ideone.com/lYBzpL
sumber
Solusi STL non-sgi, non-boost terbaik adalah memperluas peta :: iterator seperti:
dan kemudian gunakan seperti itu:
sumber
Dengan contoh peta atom
sumber
Sedikit mirip dengan salah satu contoh di sini, disederhanakan dari
std::map
perspektif penggunaan.Gunakan seperti ini:
sumber
map.size()
berarti menggandakan pengembalian ukuran vektor. Silakan perbaiki untuk menyelamatkan orang lain sakit kepala :(Karena itu tidak bisa melakukannya lebih baik daripada Anda bisa melakukannya. Jika implementasi metode tidak akan lebih unggul daripada implementasi fungsi bebas maka secara umum Anda tidak boleh menulis metode; Anda harus menulis fungsi gratis.
Juga tidak jelas mengapa itu berguna.
sumber
empty()
karena dapat diimplementasikan sebagaisize() == 0
.std::map<T,U>
sebagai wadah pasangan. Dalam Python,dict
tindakan seperti kuncinya ketika diulangi, tetapi memungkinkan Anda mengatakand.items()
untuk mendapatkan perilaku C ++. Python juga menyediakand.values()
.std::map<T,U>
tentu saja dapat menyediakankeys()
danvalues()
metode yang mengembalikan objek yang memilikibegin()
danend()
yang menyediakan iterator atas kunci dan nilai.