DAN beberapa parameter

15
function andMultipleExpr(){
  let logicalAnd;
  let i;
  for (i = 0; i < arguments.length; i++){
    logicalAnd =  arguments[i] && arguments[i+1];
  }
  return logicalAnd;
}

console.log(andMultipleExpr(true, true, false, false));

Apa yang saya harapkan adalah mengeksekusi kode ini: true && true && false && false dan itu seharusnya mengembalikan false .

Bagaimana cara membuatnya di js? Terima kasih

Hakim Asa
sumber
Saya hanya ragu-ragu. Saya ingin memastikan apakah ide saya diformulasikan dengan baik. Jika ada cara yang lebih baik, silakan sarankan.
Hakim Asa
Apa yang harus menjadi output ketika nilai Troothy digunakan alih-alih boolean? yaitu andMultipleExpr(1, 1, 0, 0)atauandMultipleExpr(1, 1, 1, 1)
nick zoum
Juga apa yang harus menjadi output dari andMultipleExpr()(Memanggil fungsi tanpa parameter)?
nick zoum
Yah, kasus-kasus itu perlu diperhitungkan juga. :-)
Hakim Asa

Jawaban:

16

Gunakan Array.prototype.everypada semua argumen yang diteruskan untuk memeriksa apakah semuanya benar;

function andMultipleExpr(...a) {
  if(a.length === 0) return false; // return false when no argument being passed
  return a.every(Boolean);
}

console.log(andMultipleExpr(true, true, false)); // should return false
console.log(andMultipleExpr(true, true, true)); // should return true

Archie
sumber
Bisa ganti e => e === truedenganBoolean
nick zoum
@nickzoum ini akan cocok dengan semua nilai kebenaran, OP secara ketat membandingkan true.
Archie
1
@Archie - Tidak, mereka membandingkan truthy / falsy. Tidak ada ===dalam kode OP. Namun, everyide Anda tepat . Tapi .every(e => e)lakukan saja pekerjaannya.
TJ Crowder
@TJCrowder ya baru saja memperhatikan itu. Sudah memperbarui jawabannya. Terima kasih :)
Archie
Jika Anda menambahkan fungsi pembantu: const isTrue = x => x === true(atau x => !!xuntuk semua nilai kebenaran), Anda dapat memampatkan solusi Anda return arguments.every(isTrue). Yang bagi saya tampaknya hanya indah.
mbojko
9

Kamu butuh

  1. Mulai dengan logicalAndset ketrue

  2. Gunakan logicalAndsaat memperbaruinya, daripada menggunakan dua entri dariarguments

Perubahan minimal adalah:

function andMultipleExpr(){
    let logicalAnd = true; // ***
    let i;
    for (i = 0; i < arguments.length; i++){
        logicalAnd = logicalAnd && arguments[i]; // ***
    }
    return logicalAnd;
}
console.log(andMultipleExpr(true, true, false, false));

Tetapi solusi mbojko memiliki keuntungan dari hubungan arus pendek (menghentikan loop ketika pertama kali menemukan nilai palsu), yang sepertinya ide yang bagus.

Karena Anda menggunakan ES2015 +, Anda mungkin harus menggunakan parameter lainnya daripada arguments, dan Anda dapat menggunakan for-ofloop:

function andMultipleExpr(...flags) {
    let logicalAnd = true;
    for (const flag of flags) {
        logicalAnd = logicalAnd && flag;
    }
    return logicalAnd;
}
console.log(andMultipleExpr(true, true, false, false));

Anda juga dapat melakukan hubungan pendek yang sesuai dengan pendekatan mbojko

function andMultipleExpr(...flags) {
    for (const flag of flags) {
        if (!flag) {
            return false;
        }
    }
    return true;
}
console.log(andMultipleExpr(true, true, false, false));

Beberapa orang mungkin setuju reducedengan hal ini, tetapi solusi Archieevery jauh lebih baik. (Tapi karena perbandinganmu tidak ketat, aku akan membuatnya .every(flag => flag).)

T.J. Crowder
sumber
1
Terima kasih. Itu lebih masuk akal bagi saya :-)
Hakim Asa
Tidak perlu menambahkan parameter kedua dalam pernyataan pengurangan dalam kasus ini, mendapatkan parameter pertama secara default juga akan berfungsi.
nick zoum
1
@nickzoum - Hanya jika kita dapat mengasumsikan bahwa fungsi tidak akan pernah dipanggil tanpa argumen, karena [].reduce((a,b)=>a && b)melempar.
TJ Crowder
6

Pengembalian awal harus membuat kode lebih efisien dan lebih pendek:

function andMultipleExpr() {
  for (let i = 0; i < arguments.length; i++) {
    if (!arguments[i]) {
      return false;
    }
  }

  return true;
}
mbojko
sumber
4

Saya pikir ini cara yang sangat singkat menggunakan ES6 Array.prototype.reduce

let andMultipleExpr = (...args) => args.reduce((a, b) => a && b);

console.log(andMultipleExpr(true, true, false, false));

Untuk penjelasan lebih lanjut tentang pengurangan fungsi, silakan baca MDN

Patrissol Kenfack
sumber
Jika Anda menggunakan metode array, lebih baik menggunakan everyseperti yang dilakukan Archie daripada reduce. Lebih sederhana, dan sirkuit pendek.
TJ Crowder
Itu benar. Tapi mari kita tinggal sekarang dia mau tapi LOGIS ATAU | sekarang dengan pengurangan, itu hanya akan berubah && ke ||
Patrissol Kenfack
Atau everyuntuk some. Masih lebih sederhana. Masih hubungan arus pendek.
TJ Crowder
Sudah selesai dilakukan dengan baik. Anda benar @TJCrowder
Patrissol Kenfack
3

Anda bisa mengambil Array#everydan mengembalikan nilai terakhir.

Pendekatan ini mengembalikan hasil nyata dari AND&& .

Dengan menggunakan pendekatan, hubung singkat dibuat untuk nilai falsy pertama yang ditemukan. Kemudian iterasi berhenti.

function andMultipleExpr(...args) {
    var result; // any return value is configurable for empty args
    args.every(v => result = v);
    return result;
}

console.log(andMultipleExpr(true, true, false, false));
console.log(andMultipleExpr(true, true, 1, 2));
console.log(andMultipleExpr(true, 0, 1, 2));

Nina Scholz
sumber
3

Mungkin Anda ingin mendengar apa yang salah dengan loop:

for (i = 0; i < arguments.length; i++){
  logicalAnd =  arguments[i] && arguments[i+1];
}
  1. loop ini menyimpan &&dua item terakhir yang dihadapinya. Dalam kasus ideal ini akan &&menyatukan dua elemen terakhir dari array (yang sudah bukan yang Anda butuhkan)
  2. di atas itu pada akhir loop i=arguments.length-1, itu akan memeriksa elemen terakhir dari array, dan i+1merupakan elemen "setelah" yang terakhir, yaitu undefined. Dalam hal hubungan logis, itu dianggap false, tetapi &&menghasilkan nilai itu sendiri dalam kasus seperti itu, dan itulah sebabnya fungsi kembali undefinedsepanjang waktu (ini bisa saja disebutkan dalam pertanyaan).

Documents

expr1 && expr2: Jika expr1dapat dikonversi menjadi true, mengembalikan expr2; lain, kembali expr1.

arr=[true];
console.log("your case:",arr[0] && arr[1]);

console.log("1 && 2:", 1 && 2);


Sebaliknya, Anda harus menggunakan logicalAndsebagai akumulator, yang mengumpulkan hasil dari &&-semua elemen sebelumnya, dan trik yang dapat Anda gunakan adalah jika hasil dari sebagian &&adalah false, tidak masalah apa elemen yang tersisa, hasil akhirnya akan jadi false, sehingga loop dapat segera berhenti:

function andMultipleExpr(){
    let logicalAnd = arguments[0] || false;
    for (let i = 1; i < arguments.length && logicalAnd; i++){
        logicalAnd = logicalAnd && arguments[i];
    }
    return logicalAnd;
}

console.log("():",andMultipleExpr());
console.log("(false):",andMultipleExpr(false));
console.log("(true):",andMultipleExpr(true));
console.log("(true,true):",andMultipleExpr(true,true));
console.log("(true, true, false, false):",andMultipleExpr(true, true, false, false));

dan kemudian Anda dapat mengoptimalkannya terhadap jawaban Archie : hasil dari &&item -ing adalah truejika semua item true, dan Anda tidak harus menjalankan &&operasi tunggal untuk menghitung hasilnya:

function andMultipleExpr(){
    if(arguments.length===0){
      return false;
    }
    for (let i = 0; i < arguments.length; i++){
      if(!arguments[i]){
        return false;
      }
    }
    return true;
}

console.log("():",andMultipleExpr());
console.log("(false):",andMultipleExpr(false));
console.log("(true):",andMultipleExpr(true));
console.log("(true,true):",andMultipleExpr(true,true));
console.log("(true, true, false, false):",andMultipleExpr(true, true, false, false));

(Dalam cuplikan di atas saya bertujuan untuk menghasilkan falsedaftar argumen kosong.)

tevemadar
sumber