Javascript foreach loop pada objek array asosiatif

182

Mengapa for-for loop saya tidak mengulangi objek array asosiatif JavaScript saya?

// defining an array
var array = [];

// assigning values to corresponding keys
array["Main"] = "Main page";
array["Guide"] = "Guide page";
array["Articles"] = "Articles page";
array["Forum"] = "Forum board";

// expected: loop over every item,
// yet it logs only "last" assigned value - "Forum"
for (var i = 0; i < array.length; i++) {
    console.log(array[i]);
}

EDIT: jQuery each()dapat membantu: https://api.jquery.com/jQuery.each/

Szymon Toda
sumber
1
Anda membuat array tetapi kemudian menggunakannya sebagai peta. Sepertinya Anda menginginkan objek biasa.
Jon
4
Tidak ada hal-hal seperti associative arraysdi JS: itu baik Array atau Obyek. Tidak ada yang mencegah menambahkan properti non-numerik Array, tapi itu tidak membuatnya associative- khususnya, lengthproperti tidak akan menghitung-otomatis properti ini.
raina77ow
3
re: Tidak ada yang namanya array asosiatif di JS. - worded cara lain: JavaScript menggunakan nama "Objek" bukan nama "array asosiatif". Tetapi tidak memiliki properti ".length".
Jesse Chisholm

Jawaban:

315

The .lengthproperti hanya melacak properti dengan indeks numerik (kunci). Anda menggunakan string untuk kunci.

Kamu bisa melakukan ini:

var arr_jq_TabContents = {}; // no need for an array

arr_jq_TabContents["Main"] = jq_TabContents_Main;
arr_jq_TabContents["Guide"] = jq_TabContents_Guide;
arr_jq_TabContents["Articles"] = jq_TabContents_Articles;
arr_jq_TabContents["Forum"] = jq_TabContents_Forum;

for (var key in arr_jq_TabContents) {
    console.log(arr_jq_TabContents[key]);
}

Agar aman, itu ide yang bagus dalam loop seperti itu untuk memastikan bahwa tidak ada properti yang merupakan hasil pewarisan yang tidak terduga:

for (var key in arr_jq_TabContents) {
  if (arr_jq_TabContents.hasOwnProperty(key))
    console.log(arr_jq_TabContents[key]);
}

sunting - mungkin ide yang bagus sekarang untuk mencatat bahwa Object.keys()fungsi ini tersedia di browser modern dan di Node dll. Fungsi itu mengembalikan kunci "milik sendiri" suatu objek, sebagai sebuah array:

Object.keys(arr_jq_TabContents).forEach(function(key, index) {
  console.log(this[key]);
}, arr_jq_TabContents);

Fungsi panggilan balik yang dilewati .forEach()dipanggil dengan setiap tombol dan indeks kunci dalam array dikembalikan oleh Object.keys(). Itu juga melewati array yang melaluinya fungsi iterating, tetapi array itu tidak benar-benar berguna bagi kita; kita membutuhkan objek aslinya . Itu dapat diakses secara langsung dengan nama, tetapi (menurut saya) itu sedikit lebih baik untuk meneruskannya secara eksplisit, yang dilakukan dengan memberikan argumen kedua ke .forEach()- objek asli - yang akan terikat seperti thisdi dalam callback. (Hanya melihat bahwa ini dicatat dalam komentar di bawah.)

Runcing
sumber
Whats ini var arr_jq_TabContents = {};? Maksud saya {}
Szymon Toda
1
@ Ultra itu adalah objek kosong literal. Ini hanya berarti bahwa variabel diinisialisasi dengan referensi ke objek kosong baru.
Runcing
@Ultra Anda tidak memerlukan instance Array karena dalam kode itu Anda tidak menggunakannya seperti array JavaScript. JavaScript tidak memiliki "array asosiatif" seperti beberapa bahasa lainnya.
Runcing
1
Apa perbedaan antara penetapan []dan {}? Hanya prototipe yang berbeda?
SoonDead
8
Alih-alih menggunakan hasOwnProperty, harus dimungkinkan di semua peramban web modern untuk beralih menggunakan kunci objek menggunakan: Object.keys(arr_jq_TabContents).forEach( function(key) { ... } );
Gregory Bell
80

Ini adalah pendekatan yang sangat sederhana. Keuntungannya adalah Anda bisa mendapatkan kunci juga:

for (var key in array) {
    var value = array[key];
    console.log(key, value);
}

Untuk ES6:

array.forEach(value => {
  console.log(value)
})  

Untuk ES6: (Jika Anda ingin nilai, indeks dan array itu sendiri)

array.forEach((value, index, self) => {
  console.log(value, index, self)
})  
tika
sumber
12
Jangan gunakan vardalam loop yang menyarankan pelingkupan yang tidak ada. Gunakan vardi depan loop atau letdi loop.
ceving
2
@ceving, dapatkah Anda menjelaskan lebih lanjut mengapa tidak menggunakan var in loop? Saya berasal dari latar belakang C ++ / PHP dan saya tidak mengerti ini. pelingkupan memang ada di loop, tapi sementara, jadi saya tidak yakin apa yang Anda maksud.
Dennis
6
@ Dennis Dalam kebanyakan bahasa deklarasi variabel dalam satu forloop menghasilkan lingkup terbatas pada tubuh forloop. Namun dalam JavaScript, variabel yang dideklarasikan oleh varselalu berfungsi global meskipun Anda menulisnya dalam satu forlingkaran. Lihat di sini: davidwalsh.name/for-and-against-let
ceving
1
bukan kebocoran memori per se, tapi pasti "memori tumpah". vardi Javascript membuat variabel dalam memori bahkan setelah loop selesai.
ahnbizcad
Saya pikir inti dari komentar ini mengenai penggunaan "var" adalah sekarang menggunakan "biarkan" secara umum tetapi secara khusus dalam satu lingkaran. Alasannya dijelaskan di atas tetapi dalam ringkasan itu karena ruang lingkup, "var" menciptakan ruang lingkup global.
DeeZone
6

Sudah ada beberapa contoh langsung, tapi saya perhatikan dari bagaimana Anda mengatakan pertanyaan Anda bahwa Anda mungkin berasal dari latar belakang PHP, dan Anda mengharapkan JavaScript bekerja dengan cara yang sama - tidak. PHP arraysangat berbeda dari JavaScript Array.

Dalam PHP, array asosiatif dapat melakukan sebagian besar dari apa yang dapat diindeks oleh array numerik ( array_*fungsi berfungsi, Anda bisa count(), dll.) Anda cukup membuat array dan mulai menetapkan ke string-indeks bukan numerik.

Dalam JavaScript, semuanya adalah objek (kecuali untuk primitif: string, numerik, boolean), dan array adalah implementasi tertentu yang memungkinkan Anda memiliki indeks numerik. Apa pun mendorong ke array akan mempengaruhi nya length, dan dapat mengulangi lebih menggunakan metode Array ( map, forEach, reduce, filter, find, dll) Namun, karena segala sesuatu adalah obyek, Anda selalu bebas untuk hanya sifat assign, karena itu sesuatu yang Anda lakukan untuk objek apa saja. Notasi persegi-braket hanyalah cara lain untuk mengakses properti, jadi dalam kasus Anda:

array['Main'] = 'Main Page';

sebenarnya setara dengan:

array.Main = 'Main Page';

Dari uraian Anda, dugaan saya adalah Anda menginginkan 'array asosiatif', tetapi untuk JavaScript, ini adalah kasus sederhana menggunakan objek sebagai hashmap. Juga, saya tahu ini adalah contoh, tetapi hindari nama-nama yang tidak bermakna yang hanya menggambarkan tipe variabel (misalnya array), dan nama berdasarkan apa yang seharusnya berisi (misalnya pages). Objek sederhana tidak memiliki banyak cara langsung yang baik untuk beralih, jadi sering kali kita akan berubah menjadi array terlebih dahulu menggunakan Objectmetode ( Object.keysdalam hal ini - ada juga entriesdan valuesditambahkan ke beberapa browser sekarang) yang dapat kita loop.

// assigning values to corresponding keys
const pages = {
  Main: 'Main page',
  Guide: 'Guide page',
  Articles: 'Articles page',
  Forum: 'Forum board',
};

Object.keys(pages).forEach((page) => console.log(page));
Josh dari Qaribou
sumber
4

arr_jq_TabContents[key] melihat array sebagai bentuk indeks-0.

MSO
sumber
4

Berikut adalah cara sederhana untuk menggunakan array asosiatif sebagai tipe Objek generik:

Object.prototype.forEach = function(cb){
   if(this instanceof Array) return this.forEach(cb);
   let self = this;
   Object.getOwnPropertyNames(this).forEach(
      (k)=>{ cb.call(self, self[k], k); }
   );
};

Object({a:1,b:2,c:3}).forEach((value, key)=>{ 
    console.log(`key/value pair: ${key}/${value}`);
});

Chouettou
sumber
1

Ini (pada dasarnya) salah dalam banyak kasus:

var array = [];
array["Main"] = "Main page";

Itu menciptakan properti non-elemen pada array dengan nama Main. Meskipun array adalah objek, biasanya Anda tidak ingin membuat properti non-elemen.

Jika Anda ingin mengindeks arraydengan nama-nama itu, biasanya Anda akan menggunakan Mapobjek polos, bukan array.

Dengan Map(ES2015 +), yang akan saya panggil mapkarena saya kreatif:

let map = new Map();
map.set("Main", "Main page");

Anda kemudian iterate itu menggunakan iterator dari yang values, keysatau entriesmetode, misalnya:

for (const value of map.values()) {
    // Here, `value` will be `"Main page"`, etc.
}

Menggunakan objek biasa, yang akan saya sebut kreatif obj:

let obj = Object.create(null); // Creates an object with no prototype
obj.Main = "Main page"; // Or: `obj["Main"] = "Main page";`

Anda akan kemudian iterate isinya menggunakan Object.keys, Object.valuesatau Object.entries, misalnya:

for (const value of Object.values(proches_X)) {
    // Here, `value` will be `"Main page"`, etc.
}
TJ Crowder
sumber
0

var obj = {
  no: ["no", 32],
  nt: ["no", 32],
  nf: ["no", 32, 90]
};

count = -1; // which must be static value
for (i in obj) {
  count++;
  if (obj.hasOwnProperty(i)) {
    console.log(obj[i][count])
  };
};

dalam kode ini saya menggunakan metode tanda kurung untuk nilai-nilai panggilan dalam array karena berisi array, namun secara singkat gagasan yang variabel saya memiliki kunci properti dan dengan loop yang disebut kedua nilai array asosiasi

Metode sempurna, jika Anda tertarik, tekan suka

Dev-Wb Ahmed
sumber
Anda tidak mengulang-ulang array, Anda mengulang-ulang objek yang memiliki array dalam kunci-kunci itu .. Silakan baca pertanyaannya dan lihat contohnya.
Pedro Joaquín
0

Kamu bisa melakukan ini

var array = [];

// assigning values to corresponding keys
array[0] = "Main page";
array[1] = "Guide page";
array[2] = "Articles page";
array[3] = "Forum board";


array.forEach(value => {
    console.log(value)
})
Shuvro
sumber