Membangun objek dengan mengulang dua array

Cukup mudah.

Saya perlu membuat fungsi objOfMatches yang menerima dua array dan panggilan balik. objOfMatches akan membuat objek dan mengembalikannya. Untuk membangun objek, objOfMatches akan menguji setiap elemen larik pertama menggunakan panggilan balik untuk melihat apakah keluarannya cocok dengan elemen terkait (menurut indeks) larik kedua. Jika ada kecocokan, elemen dari array pertama menjadi kunci dalam suatu objek, dan elemen dari array kedua menjadi nilai yang sesuai.

function objOfMatches(array1, array2, callback) {
    //create obj
    var obj = {}

    //loop thru first array
    for(let i = 0; i < array1.length; i++) {
        for (let j = 0; j < array2.length; j++) {
            if (callback(array1[i]) === array2[j]) {                
                obj.array1[i] = array2[j];
            }
        }
    }
    return obj;
}

console.log(objOfMatches(['hi', 'howdy', 'bye', 'later', 'hello'], ['HI', 'Howdy', 'BYE', 'LATER', 'hello'], function(str) { return str.toUpperCase(); }));
// should log: { hi: 'HI', bye: 'BYE', later: 'LATER' }

Kelihatannya cukup sederhana, namun saya tidak sepenuhnya memahami mengapa ia memunculkan TypeError di konsol. (TypeError: Cannot set property '0' of undefined)

Bisakah seseorang menjelaskan apa yang terjadi?


person leonardofed    schedule 13.09.2018    source sumber
comment
Coba obj[array1[i]] = array2[j];.   -  person Ori Drori    schedule 13.09.2018
comment
@OriDrori uhm, ini berhasil. Kedengarannya aneh, tapi obj.array1[i] = array2[j]; tidak terlihat seperti kesalahan sintaksis. Saya jelas-jelas salah.   -  person leonardofed    schedule 13.09.2018
comment
Memang tidak, tapi maknanya tidak seperti yang Anda pikirkan. obj.array1[i] = array2[j] -›set indeks i dari array properti obj ke suatu nilai, dan tidak mengatur kunci dengan nama teks yang ada di indeks i dalam array.   -  person Ori Drori    schedule 13.09.2018
comment
itu disebut notasi braket. Anda dapat menggunakannya untuk mengakses atau mengatur properti suatu objek.   -  person oosniss    schedule 13.09.2018
comment
Mengapa 'hello' bukan bagian dari hasil yang Anda harapkan?   -  person connexo    schedule 14.09.2018
comment
Dan kenapa howdy juga tidak ada di dalamnya? Ini sama sekali tidak cukup mudah.   -  person connexo    schedule 14.09.2018
comment
@connexo lihat panggilan balik yang diteruskan ke objOfMatches.   -  person leonardofed    schedule 14.09.2018
comment
Itu selalu membantu membungkus antrean panjang ;)... Menyesuaikan jawaban saya.   -  person connexo    schedule 14.09.2018


Jawaban (3)


Jika Anda ingin mencocokkan elemen sesuai Anda tidak perlu mengulang kedua array. Anda dapat mengulang salah satunya dan menggunakan indeks untuk menemukan objek terkait di objek lainnya.

reduce() cocok untuk ini karena ini akan memungkinkan Anda membangun objek pengembalian di tempatnya dan menyediakan indeks dari iterasi loop saat ini. Anda cukup menjalankan pengujian dan menetapkan kunci/nilai jika pengujian tersebut benar.

function objOfMatches(arr1, arr2, callback){
  return arr1.reduce((obj, current, index) => {
    if(arr2[index] === callback(current)) obj[current] = arr2[index]
    return obj
  }, {})
}

console.log(objOfMatches(['hi', 'howdy', 'bye', 'later', 'hello'], ['HI', 'Howdy', 'BYE', 'LATER', 'hello'], function(str) { return str.toUpperCase(); }));

person Mark    schedule 13.09.2018
comment
Mark yang bagus. - person leonardofed; 14.09.2018

Dengan asumsi kedua array memiliki panjang yang sama dan indeks elemen yang cocok cocok, pengurangan yang sangat mudah akan membawa Anda ke sana:

const x = ['hi', 'howdy', 'bye', 'later', 'hello'],
      y = ['HI', 'Howdy', 'BYE', 'LATER', 'hello'];

console.log(x.reduce((a,v,i)=>Object.assign(a,{[v]:y[i]}),{}))

Jika Anda perlu memeriksa keberadaan dan posisi kecocokan, inilah yang perlu Anda modifikasi agar Array.prototype.reduce berfungsi untuk Anda:

const x = ['hi', 'later', 'howdy', 'bye', 'hello', 'foo'],
      y = ['HI', 'baz', 'Howdy', 'BYE', 'LATER', 'hello', 'bar'];

console.log(x.reduce((a,v)=> {
    let i = y.indexOf(v.toUpperCase())
    return i === -1 ? a : Object.assign(a, {[v]:y[i]})
  },{}
))

person connexo    schedule 13.09.2018

Mengikuti pendekatan Anda, Anda harus menggunakan obj[array1[j]] = array2[i] ini, berikut contohnya:

function objOfMatches(array1, array2, callback) {
    //create obj
    var obj = {}

    //loop thru first array
    for(let i = 0; i < array1.length; i++) {
        for (let j = 0; j < array2.length; j++) {
            if (callback(array1[i]) === array2[j]) {   
                if(!array1[j] in obj) obj[array1[j]]  = [] 
                obj[array1[j]] = array2[i];
            }
        }
    }
    return obj;
}

console.log(objOfMatches(['hi', 'howdy', 'bye', 'later', 'hello'], ['HI', 'Howdy', 'BYE', 'LATER', 'hello'], function(str) { return str.toUpperCase(); }));

person Emeeus    schedule 13.09.2018
comment
Hai Emeeus, solusi ini cukup instruktif. Bisakah Anda menjelaskan lebih lanjut pernyataan if yang disarangkan? Khususnya, bagian ini: if(!array1[j] in obj) obj[array1[j]] = [] obj[array1[j]] = array2[i];. Terima kasih - person Codestudio; 06.07.2020