และหลายพารามิเตอร์


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));

สิ่งที่ผมคาดหวังคือการรันโค้ดนี้จริงจริง && && && เท็จเท็จและที่ควรกลับเท็จ

วิธีที่จะทำให้งานใน js? ขอบคุณ


ฉันแค่ลังเล ฉันต้องการแน่ใจว่าแนวคิดของฉันดีหรือไม่ หากมีวิธีที่ดีกว่าโปรดแนะนำ
Hakim Asa

อะไรควรเป็นผลลัพธ์เมื่อใช้ค่า Troothy แทน booleans เช่นandMultipleExpr(1, 1, 0, 0)หรือandMultipleExpr(1, 1, 1, 1)
nick zoum

นอกจากนี้สิ่งที่ควรจะเป็นผลลัพธ์ของandMultipleExpr()(เรียกฟังก์ชั่นโดยไม่มีพารามิเตอร์)?
Nick zoum

กรณีเหล่านี้ต้องถูกนำมาพิจารณาด้วยเช่นกัน :-)
Hakim Asa

คำตอบ:


16

ใช้Array.prototype.everyอาร์กิวเมนต์ที่ส่งผ่านทั้งหมดเพื่อตรวจสอบว่าทั้งหมดเป็นจริงหรือไม่

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


สามารถแทนที่e => e === trueด้วยBoolean
nick zoum

@nickzoum นี้จะตรงกับค่า truthy ทั้งหมด OP trueจะเปรียบเทียบอย่างเคร่งครัด
อาร์ชี

1
@Archie - ไม่พวกเขากำลังเปรียบเทียบความจริง / เท็จ ไม่มี===ในรหัสของ OP everyความคิดของคุณอยู่ตรงจุดแม้ว่า แต่.every(e => e)ทำงานได้ดี
TJ Crowder

@TJCrowder ใช่เพิ่งสังเกตเห็นว่า อัปเดตคำตอบแล้ว ขอบคุณ :)
Archie

ถ้าคุณเพิ่มฟังก์ชั่นผู้ช่วย: const isTrue = x => x === true(หรือx => !!xค่า truthy ทั้งหมด) return arguments.every(isTrue)คุณสามารถบีบอัดวิธีการแก้ปัญหาของคุณลงใน ซึ่งสำหรับฉันดูเหมือนว่าสวยงามเพียง
mbojko

9

คุณจำเป็นต้อง

  1. เริ่มต้นด้วยการlogicalAndตั้งค่าเป็นtrue

  2. ใช้logicalAndเมื่ออัปเดตแทนที่จะใช้สองรายการจากarguments

การเปลี่ยนแปลงที่น้อยที่สุดคือ:

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));

แต่วิธีการแก้ปัญหาของ mbojkoมีข้อดีของการลัดวงจร (หยุดลูปเมื่อพบค่าเท็จ) ซึ่งดูเหมือนเป็นความคิดที่ดี

เนื่องจากคุณใช้ ES2015 + คุณควรใช้พารามิเตอร์ที่เหลือแทนargumentsและคุณสามารถใช้การfor-ofวนซ้ำได้:

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

นอกจากนี้คุณยังสามารถลัดวงจรเพื่อให้สอดคล้องกับแนวทางของ mbojko

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

บางคนอาจจะโยนreduceสิ่งนี้ แต่ทางออกของอาร์ชีeveryนั้นดีกว่ามาก (แต่เนื่องจากการเปรียบเทียบของคุณไม่เข้มงวดฉันแค่ทำมัน.every(flag => flag))


1
ขอบคุณ นั่นสมเหตุสมผลมากสำหรับฉัน :-)
Hakim Asa

ไม่จำเป็นต้องเพิ่มพารามิเตอร์ที่สองในคำสั่งลดในกรณีนี้รับพารามิเตอร์แรกโดยค่าเริ่มต้นจะทำงาน
Nick zoum

1
@nickzoum - เฉพาะในกรณีที่เราสามารถสันนิษฐานได้ว่าฟังก์ชั่นจะไม่ถูกเรียกด้วยไม่มีข้อโต้แย้งนับตั้งแต่[].reduce((a,b)=>a && b)พ่น
TJ Crowder

6

การส่งคืนต้นควรทำให้โค้ดมีประสิทธิภาพและสั้นลง:

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

  return true;
}

4

ฉันคิดว่านี่เป็นวิธีที่สั้นมากเมื่อใช้ES6 Array.prototype.reduce

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

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

สำหรับคำอธิบายเพิ่มเติมเกี่ยวกับฟังก์ชั่นลดโปรดอ่านMDN


หากคุณทำจะใช้วิธีการอาร์เรย์ก็มากดีกว่าที่จะใช้everyเช่นอาร์ชีได้reduceมากกว่า เรียบง่ายและมันลัดวงจร
TJ Crowder

มันเป็นเรื่องจริง แต่ให้เราอยู่ตอนนี้เขาต้องการ แต่ตรรกะหรือ || ตอนนี้ด้วยการลดขนาดก็จะเปลี่ยน&&เป็น||
Patrissol Kenfack

หรือเพื่อevery someยังง่ายกว่า ยังคงเป็นวงจรสั้น
TJ Crowder

ทำได้ดี. คุณถูกต้อง @TJCrowder
Patrissol Kenfack

3

คุณสามารถรับArray#everyและคืนค่าสุดท้าย

วิธีการนี้จะส่งกลับผลที่แท้จริงของตรรกะและ&&

โดยใช้วิธีการทำให้เกิดไฟฟ้าลัดวงจรสำหรับค่าเท็จพบเป็นครั้งแรก จากนั้นการทำซ้ำจะหยุด

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));


3

บางทีคุณอยากได้ยินสิ่งผิดปกติกับลูป:

for (i = 0; i < arguments.length; i++){
  logicalAnd =  arguments[i] && arguments[i+1];
}
  1. การวนซ้ำนี้จัดเก็บ&&รายการสองรายการสุดท้ายที่พบ ในกรณีอุดมคติมันจะ&&รวมสององค์ประกอบสุดท้ายของอาร์เรย์ (ซึ่งไม่ใช่สิ่งที่คุณต้องการ)
  2. ด้านบนของที่ในตอนท้ายของวงi=arguments.length-1ก็จะตรวจสอบองค์ประกอบสุดท้ายของอาร์เรย์และi+1เป็นองค์ประกอบ "หลัง" undefinedคนสุดท้ายซึ่งเป็น ในแง่ของความสัมพันธ์เชิงตรรกะจะพิจารณาfalseแต่&&สร้างมูลค่าของตัวเองในกรณีเช่นนี้และนั่นคือเหตุผลที่ฟังก์ชั่นส่งคืนundefinedตลอดเวลา (นี้อาจได้รับการกล่าวถึงว่าในคำถาม)

เอกสาร

expr1 && expr2: หากexpr1สามารถแปลงเป็นtrueผลตอบแทนexpr2; expr1อื่นผลตอบแทน

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

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


แต่คุณควรใช้logicalAndเป็นตัวสะสมซึ่งจะรวบรวมผลลัพธ์ของ&&องค์ประกอบทั้งหมดก่อนหน้านี้และเคล็ดลับที่คุณสามารถใช้คือถ้าผลลัพธ์ของบางส่วน&&คือfalseมันไม่สำคัญว่าองค์ประกอบที่เหลือคืออะไรผลลัพธ์สุดท้าย เป็นไปได้falseดังนั้นลูปสามารถหยุดได้ทันที:

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));

และจากนั้นคุณสามารถปรับให้เหมาะสมกับคำตอบของ Archie : ผลลัพธ์ของ&&รายการไอเอ็นจีคือtrueถ้าทุกรายการเป็นtrueและคุณไม่จำเป็นต้องดำเนินการเดียว&&สำหรับการคำนวณผลลัพธ์:

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));

(ในตัวอย่างด้านบนฉันตั้งเป้าที่จะสร้างfalseรายการอาร์กิวเมนต์เปล่า)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.