TypeScript, Looping melalui kamus

186

Dalam kode saya, saya memiliki beberapa kamus (seperti yang disarankan di sini ) yang diindeks String. Karena ini adalah jenis improvisasi, saya bertanya-tanya apakah ada saran tentang bagaimana saya bisa mengulang setiap kunci (atau nilai, semua yang saya butuhkan kunci untuk tetap). Bantuan apa pun dihargai!

myDictionary: { [index: string]: any; } = {};
ben657
sumber
Apakah Anda sudah mencoba for (var key in myDictionary) { }:? Di dalam loop, Anda akan gunakan keyuntuk mendapatkan kunci, dan myDictionary[key]untuk mendapatkan nilai
Ian
@Ian Baru mencobanya, sepertinya tidak berfungsi. Tidak ada kesalahan, tetapi tidak ada yang berjalan dalam pernyataan
ben657
1
@Ian Ah maaf, beberapa kode di tempat lain mengacaukannya. Itu bekerja dengan sempurna! Peduli untuk menjadikannya jawaban sehingga saya bisa memilihnya?
ben657

Jawaban:

296

Untuk mengulangi kunci / nilai, gunakan for inloop:

for (let key in myDictionary) {
    let value = myDictionary[key];
    // Use `key` and `value`
}
Ian
sumber
8
Ini tidak aman secara umum; perlu tes hasOwnProperty (seperti pada jawaban Jamie Stark) atau yang lainnya.
Don Hatch
20
@ DonHatch Ini sebenarnya sangat aman secara umum. Ini tidak aman dalam kasus yang sangat spesifik (seperti ketika Anda menyertakan perpustakaan yang memodifikasi prototipe secara tidak benar, atau sengaja memodifikasi prototipe secara salah). Terserah pengembang apakah akan menggembungkan kode mereka dengan cek yang kemungkinan besar tidak perlu
Ian
1
@Ian - Pemikiran saya adalah bahwa saya tidak akan menggunakannya tanpa perlindungan tambahan karena tampaknya seperti kecelakaan yang menunggu untuk terjadi, misalnya jika kode menemukan jalannya ke fungsi utilitas, dan kemudian seseorang melewati fungsi itu sebagai kamus yang bukan sekadar Obyek, tetapi sesuatu dengan properti tambahan. Ya, seperti yang Anda katakan, tergantung pada pengembang untuk menimbang kemungkinan dan tingkat keparahan skenario semacam itu. Bagi saya sendiri, pendekatan yang paling tidak memberatkan mental adalah berperilaku seolah-olah skenario seperti itu dijamin akan terjadi dalam semua kasus - lebih sedikit untuk dipikirkan.
Don Hatch
5
@Ian Masalahnya adalah bahwa ada terlalu banyak perpustakaan yang memodifikasi prototipe objek. Tampaknya ide yang buruk untuk menganjurkan jenis pola ini ketika ada alternatif sederhana yang jauh lebih baik, seperti Object.keys(target).forEach(key => { let value = target(key); /* Use key, value here */ });. Jika Anda harus menunjukkan metode ini, setidaknya sebutkan risiko dan alternatif yang lebih baik bagi mereka yang belum tahu lebih baik.
Yona Appletree
8
Kami sudah memiliki es6 dan TypeScript. Mengapa masalah penulisan hasOwnProperty sepanjang waktu tetap belum terselesaikan? Bahkan pada 2017 dan dengan semua perhatian ke JS. Aku sangat kecewa.
Gherman
170

<ES 2017 :

Object.keys(obj).forEach(key => {
  let value = obj[key];
});

> = ES 2017 :

Object.entries(obj).forEach(
  ([key, value]) => console.log(key, value);
);
Stephen Paul
sumber
Ini adalah solusi yang saya cari karena akan memungkinkan saya untuk menyortir kunci sebelum iterasi
Andrew
FYI, ini tidak didukung di taman bermain TypeScript saat ini.
Seanny123
1
Lihat di sini cara membuatnya Object.entriesbekerja di TypeScript
Alex Klaus
Ini sempurna
Piyush Choudhary
67

Bagaimana dengan ini?

for (let [key, value] of Object.entries(obj)) {
    ...
}
Radon Rosborough
sumber
1
Ini membutuhkan lib es2017 di tsconfig. Lihat stackoverflow.com/questions/45422573/...
Stéphane
Inilah yang saya butuhkan untuk melewati kesalahan Typeftext pada obj [key] "Tidak ada indeks signature ..." karena saya secara eksplisit menetapkan tipe obj saya sebagai {[key: string]: string} dan tidak ingin menggunakan {[key: string]: any}. Dengan ini saya hanya bisa mengakses 'nilai'. Terima kasih
ggedde
Dan jika Anda ingin mengabaikan keysama sekali, hanya biarkan kosong: [ , value]. (Berkat komentar masalah ini .)
Dominik
51

Ada satu peringatan untuk loop kunci / nilai yang disebutkan Ian. Jika memungkinkan, Objek mungkin memiliki atribut yang melekat pada Prototipe mereka, dan ketika Anda menggunakan inoperator, atribut ini akan dimasukkan. Jadi, Anda ingin memastikan bahwa kuncinya adalah atribut dari instance Anda, dan bukan prototipe. IE yang lebih lama dikenal karena indexof(v)muncul sebagai kunci.

for (const key in myDictionary) {
    if (myDictionary.hasOwnProperty(key)) {
        let value = myDictionary[key];
    }
}
Jamie Starke
sumber
3
Tidak mencoba memisahkan rambut, tetapi karena kita sedang berbicara skrip jenis, bukankah seharusnya Anda menggunakan kunci let bukan var key? Jawaban yang bagus terima kasih.
Luke Dupin
3
Bahkan, dengan skrip jenis versi saat ini keydan valuebisa const.
Patrick Desjardins
Lebih baik tidak memanggil hasOwnPropertycek dari objek target, tetapi lakukan ini: ...if (Object.prototype.hasOwnProperty.call(myDictionary, key))...Lain, jika Anda menggunakan eslint dengan no-prototype-builtinsaturan, itu akan memancarkan kesalahan.
sceee
6

Cara terpendek untuk mendapatkan semua nilai kamus / objek:

Object.keys(dict).map(k => dict[k]);
k06a
sumber
1

Untuk mendapatkan kunci:

function GetDictionaryKeysAsArray(dict: {[key: string]: string;}): string[] {
  let result: string[] = [];
  Object.keys(dict).map((key) =>
    result.push(key),
  );
  return result;
}
Ribeiro
sumber
1

Ians Answer baik, tetapi Anda harus menggunakan const daripada membiarkan kunci karena tidak pernah diperbarui.

for (const key in myDictionary) {
    let value = myDictionary[key];
    // Use `key` and `value`
}
orang Finlandia
sumber