VÀ nhiều tham số


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

Điều tôi đang mong đợi là thực thi mã này: true && true && false && false và điều đó sẽ trả về false .

Làm thế nào để làm việc đó trong js? Cảm ơn


Tôi chỉ đang do dự. Tôi muốn chắc chắn nếu ý tưởng của tôi được xây dựng tốt. Nếu có một cách tốt hơn, xin vui lòng đề nghị.
Hakim Asa

Điều gì sẽ là đầu ra khi giá trị Troothy được sử dụng thay vì booleans? tức là andMultipleExpr(1, 1, 0, 0)hoặcandMultipleExpr(1, 1, 1, 1)
nick zoum

Ngoài ra những gì nên là đầu ra của andMultipleExpr()(Gọi hàm không có tham số)?
nick zoum

tốt, những trường hợp đó cũng cần phải được tính đến. :-)
Hakim Asa

Câu trả lời:


16

Sử dụng Array.prototype.everytrên tất cả các đối số được thông qua để kiểm tra xem tất cả chúng có đúng không;

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


Có thể thay thế e => e === truebằngBoolean
nick zoum

@nickzoum điều này sẽ phù hợp với tất cả các giá trị trung thực, OP đang so sánh nghiêm ngặt true.
Archie

1
@Archie - Không, họ đang so sánh sự thật / giả dối. Không có ===mã của OP. everyÝ tưởng của bạn là tại chỗ , mặc dù. Nhưng chỉ .every(e => e)làm công việc.
TJ Crowder

@TJCrowder có chỉ cần chú ý rằng. Đã cập nhật câu trả lời rồi. Cảm ơn :)
Archie

Nếu bạn thêm một hàm trợ giúp: const isTrue = x => x === true(hoặc x => !!xcho tất cả các giá trị trung thực), bạn có thể nén giải pháp của mình vào return arguments.every(isTrue). Mà với tôi dường như chỉ đẹp.
mbojko

9

Bạn cần phải

  1. Bắt đầu với logicalAndthiết lập đểtrue

  2. Sử dụng logicalAndkhi cập nhật nó, thay vì sử dụng hai mục từarguments

Thay đổi tối thiểu là:

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

Nhưng giải pháp của mbojko có lợi thế là đoản mạch (dừng vòng lặp khi lần đầu tiên tìm thấy giá trị giả), có vẻ như là một ý tưởng hay.

Vì bạn đang sử dụng ES2015 +, có lẽ bạn nên sử dụng tham số phần còn lại chứ không phải argumentsvà bạn có thể sử dụngfor-of vòng lặp:

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

Bạn cũng có thể đoản mạch phù hợp với phương pháp của mbojko

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

Một số người có thể ném reducevào điều này, nhưng giải pháp của Archieevery tốt hơn nhiều. (Nhưng vì sự so sánh của bạn không nghiêm ngặt, tôi chỉ thực hiện nó .every(flag => flag).)


1
Cảm ơn. Điều đó có ý nghĩa hơn với tôi :-)
Hakim Asa

Không cần thêm tham số thứ hai trong câu lệnh giảm trong trường hợp này, lấy tham số đầu tiên theo mặc định cũng sẽ hoạt động.
nick zoum

1
@nickzoum - Chỉ khi chúng ta có thể cho rằng hàm sẽ không bao giờ được gọi mà không có đối số, kể từ khi [].reduce((a,b)=>a && b)ném.
TJ Crowder

6

Trả về sớm sẽ làm cho mã hiệu quả hơn và ngắn hơn:

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

  return true;
}

4

Tôi nghĩ rằng đây là một cách rất ngắn khi sử dụng ES6 Array.prototype.reduce

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

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

Để được giải thích thêm về chức năng giảm, vui lòng đọc MDN


Nếu bạn đang làm để sử dụng một phương pháp mảng, đó là nhiều tốt hơn để sử dụng everynhư Archie đã làm hơn reduce. Đơn giản hơn, và nó ngắn mạch.
TJ Crowder

Đúng rồi. Nhưng hãy để chúng tôi ở lại bây giờ anh ấy muốn nhưng logic HOẶC | | bây giờ với mức giảm, nó sẽ chỉ thay đổi && thành ||
Patrissol Kenfack

Hoặc everyđể some. Vẫn đơn giản hơn. Vẫn ngắn mạch.
TJ Crowder

Làm tốt. Bạn nói đúng @TJCrowder
Patrissol Kenfack

3

Bạn có thể lấy Array#everyvà trả lại giá trị cuối cùng.

Cách tiếp cận này trả về kết quả thực sự của logic AND&& .

Bằng cách sử dụng phương pháp này, một mạch ngắn được tạo ra cho giá trị giả được tìm thấy đầu tiên. Sau đó lặp lại dừng lại.

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

Có lẽ bạn muốn nghe những gì đã xảy ra với vòng lặp:

for (i = 0; i < arguments.length; i++){
  logicalAnd =  arguments[i] && arguments[i+1];
}
  1. vòng lặp này lưu trữ &&hai mục cuối cùng mà nó gặp phải. Trong trường hợp lý tưởng, nó sẽ &&kết hợp hai phần tử cuối cùng của mảng (vốn không phải là thứ bạn cần)
  2. ở trên cùng ở cuối vòng lặp i=arguments.length-1, nó sẽ kiểm tra phần tử cuối cùng của mảng và i+1là phần tử "sau" phần tử cuối cùng undefined. Về mặt quan hệ logic, nó được xem xét false, nhưng tự &&tạo ra giá trị trong trường hợp đó và đó là lý do tại sao hàm trả về undefinedmọi lúc (điều này có thể đã được đề cập trong câu hỏi).

Tài liệu

expr1 && expr2: Nếu expr1có thể được chuyển đổi thành true, trả về expr2; khác, trả lại expr1.

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

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


Thay vào đó, bạn nên sử dụng logicalAndnhư một bộ tích lũy, thu thập kết quả của &&-ing tất cả các phần tử trước đó và một mẹo mà bạn có thể sử dụng là nếu kết quả của một phần &&false, không quan trọng các phần tử còn lại là gì, kết quả cuối cùng là gì sẽ xảy ra false, vì vậy vòng lặp có thể dừng ngay lập tức:

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

và sau đó bạn có thể tối ưu hóa nó theo câu trả lời của Archie : kết quả của &&các mục -ing là truenếu tất cả các mục là truevà bạn không phải thực hiện một &&thao tác duy nhất để tính kết quả:

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

(Trong đoạn trích ở trên, tôi nhắm đến việc tạo ra falsemột danh sách đối số trống.)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.