Cách viết biểu thức toán tử bậc ba (còn gọi là if) mà không cần tự lặp lại


104

Ví dụ, một cái gì đó như thế này:

var value = someArray.indexOf(3) !== -1 ? someArray.indexOf(3) : 0

Có cách nào tốt hơn để viết điều đó không? Một lần nữa, tôi không tìm kiếm câu trả lời cho câu hỏi chính xác ở trên, chỉ là một ví dụ về thời điểm bạn có thể lặp lại các toán hạng trong biểu thức toán tử bậc ba ...


2
Vì vậy, một ifvà không phải là mộtif/else
zer00ne

53
just an example of when you might have repeated things in the ternarykhông lặp lại các biểu thức đã tính. Đó là những gì các biến dành cho.
vol7ron

4
Làm thế nào để chúng tôi xác định rằng 3không phải là ở chỉ số 0của someArray?
khách271314

3
Mục tiêu của bạn ở đây là gì? Bạn đang cố gắng giảm độ dài dòng, hoặc đặc biệt cố gắng tránh lặp lại một biến trong một bậc ba? Cái trước thì có thể, cái sau thì không (ít nhất, không sử dụng các cụm từ).
asgallant

5
Tại sao không sử dụng Math.max(someArray.indexOf(3), 0)thay thế?
301_Moved_Permanently

Câu trả lời:


176

Cá nhân tôi thấy cách tốt nhất để làm điều này vẫn là ifcâu nói cũ :

var value = someArray.indexOf(3);
if (value === -1) {
  value = 0;
}

32
Để rõ ràng, câu trả lời này ủng hộ việc sử dụng một biến để lưu trữ một kết quả trung gian, chứ không phải việc sử dụng một ifcâu lệnh thay cho một bậc ba. Các câu lệnh bậc ba vẫn thường hữu ích để thực hiện một lựa chọn như một phần của một biểu thức.
Triptych

4
@Triptych: Nhìn lại lần nữa. Nó không sử dụng một biến trung gian nào cả. Thay vào đó, nó chỉ định kết quả trực tiếp cho biến cuối cùng và sau đó ghi đè lên nó nếu điều kiện được đáp ứng.
slbetman

14
Sai. Giá trị được lưu trữ valuesau dòng đầu tiên là giá trị trung gian. Nó không chứa giá trị chính xác mà sau đó được cố định trên dòng tiếp theo và do đó nó là giá trị trung gian. Chỉ sau khi ifcâu lệnh kết thúc mới valuechứa giá trị chính xác. Các bậc ba trong OP là một giải pháp tốt hơn vì nó không bao giờ đi vào trạng thái trung gian.
Jack Aidley

44
@JackAidley: "Mối mọt trong OP là giải pháp tốt hơn vì nó không bao giờ chuyển sang trạng thái trung gian." - Tôi sẽ phải không đồng ý. Điều này dễ đọc hơn rất nhiều so với mã của OP, và hoàn toàn mang tính thành ngữ. Nó cũng làm cho một lỗi trong logic của OP rõ ràng hơn một chút đối với tôi (Cụ thể, điều gì sẽ xảy ra nếu indexOf () trả về số 0? Làm cách nào để bạn phân biệt số 0 "thực" với số 0 "không tìm thấy"?).
Kevin,

2
điều này gần với những gì tôi sẽ làm, ngoại trừ valueở đây là đột biến về mặt kỹ thuật, điều mà tôi cố gắng tránh.
Dave Cousineau

102

Mã phải dễ đọc, do đó, ngắn gọn không có nghĩa là ngắn gọn bất cứ giá nào - vì vậy bạn nên đăng lại lên https://codegolf.stackexchange.com/ - vì vậy thay vào đó, tôi khuyên bạn nên sử dụng biến cục bộ thứ hai có tên indexđể tối đa hóa khả năng đọc hiểu ( với chi phí thời gian chạy tối thiểu, tôi lưu ý):

var index = someArray.indexOf( 3 );
var value = index == -1 ? 0 : index;

Nhưng nếu bạn thực sự muốn cắt giảm biểu hiện này, vì bạn là một kẻ tàn bạo tàn nhẫn với đồng nghiệp hoặc cộng tác viên dự án của mình, thì đây là 4 cách tiếp cận bạn có thể sử dụng:

1: Biến tạm thời trong một varcâu lệnh

Bạn có thể sử dụng varkhả năng của câu lệnh để xác định (và gán) một biến tạm thời thứ hai indexkhi được phân tách bằng dấu phẩy:

var index = someArray.indexOf(3), value = index !== -1 ? index: 0;

2: Chức năng ẩn danh tự thực hiện

Một tùy chọn khác là một chức năng ẩn danh tự thực thi:

// Traditional syntax:
var value = function( x ) { return x !== -1 ? x : 0 }( someArray.indexOf(3) );

// ES6 syntax:
var value = ( x => x !== -1 ? x : 0 )( someArray.indexOf(3) );

3: Toán tử dấu phẩy

Ngoài ra còn có "toán tử dấu phẩy" khét tiếng mà JavaScript hỗ trợ, cũng có trong C và C ++.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator

Bạn có thể sử dụng toán tử dấu phẩy khi bạn muốn bao gồm nhiều biểu thức trong một vị trí yêu cầu một biểu thức duy nhất.

Bạn có thể sử dụng nó để giới thiệu các tác dụng phụ, trong trường hợp này bằng cách gán lại cho value:

var value = ( value = someArray.indexOf(3), value !== -1 ? value : 0 );

Điều này hoạt động vì var valueđược diễn giải trước tiên (vì đó là một câu lệnh), sau đóvaluephép gán ngoài cùng bên trái, bên trong nhất và sau đó là bên phải của toán tử dấu phẩy và sau đó là toán tử bậc ba - tất cả đều là JavaScript hợp pháp.

4: Chỉ định lại trong một biểu thức con

Bình luận viên @IllusingBrian đã chỉ ra rằng việc sử dụng toán tử dấu phẩy (trong ví dụ trước) là không cần thiết nếu phép gán cho valueđược sử dụng như một biểu thức con có dấu ngoặc đơn:

var value = ( ( value = someArray.indexOf(3) ) !== -1 ? value : 0 );

Lưu ý rằng việc sử dụng phủ định trong các biểu thức logic có thể khó làm theo đối với con người hơn - vì vậy tất cả các ví dụ trên có thể được đơn giản hóa để đọc bằng cách thay đổi idx !== -1 ? x : ythành idx == -1 ? y : x:

var value = ( ( value = someArray.indexOf(3) ) == -1 ? 0 : value );

97
Tất cả những thứ này đều là kiểu mã hóa "thông minh" khiến tôi nhìn chằm chằm vào nó trong vài giây trước khi nghĩ "huh, tôi đoán nó hoạt động." Chúng không giúp làm rõ ràng, và vì mã được đọc nhiều hơn nó được viết nên quan trọng hơn.
Gavin S. Yancey

18
@ g.rocket cách tiếp cận 1 có thể đọc và rõ ràng 100% và là cách duy nhất để thực hiện nếu bạn muốn tránh lặp lại (điều đó có thể thực sự có hại nếu bạn đang gọi một số hàm phức tạp và có vấn đề thay vì một hàm đơn giản indefOf)
edc65

5
Đồng ý, # 1 là rất dễ đọc và dễ bảo trì, hai thứ còn lại không quá nhiều.
forgivenson

6
Đối với # 3, tôi tin rằng bạn có thể đơn giản hóa var value = ((value = someArray.indexOf(3)) === -1 ? 0 : value);thay vì sử dụng dấu phẩy.
Ảo tưởngBrian

2
Trong ví dụ thứ hai, hàm ẩn danh tự thực thi, bạn có thể bỏ qua dấu ngoặc đơn khỏi hàm arrow. var value = ( x => x !== -1 ? x : 0 ) ( arr.indexOf(3) );bởi vì chỉ là một tham số.
Alex Char

54

Đối với những con số

Bạn có thể sử dụng Math.max()chức năng.

var value = Math.max( someArray.indexOf('y'), 0 );

Nó sẽ giữ các ranh giới của kết quả 0cho đến khi kết quả đầu tiên lớn hơn 0nếu đúng như vậy. Và nếu kết quả từ indexOf-1nó sẽ trả về 0 lớn hơn -1.

Đối với giá trị boolean và boolean-y

Đối với JS không có quy luật chung AFAIK đặc biệt vì cách falsy giá trị được đánh giá.

Nhưng nếu điều gì đó có thể giúp bạn hầu hết thời gian là toán tử hoặc ( ||):

// Instead of
var variable = this_one === true ? this_one : or_this_one;
// you can use
var variable = this_one || or_this_one;

Bạn phải rất cẩn thận với điều này, bởi vì trong ví dụ đầu tiên của bạn, indexOfcó thể trở lại 0và nếu bạn đánh giá 0 || -1nó sẽ trở lại -10là một falsy giá trị.


2
Cảm ơn. Tôi đoán ví dụ của tôi là tệ, tôi chỉ đưa ra một ví dụ chung chung thôi haha ​​không tìm kiếm giải pháp cho câu hỏi chính xác. Tôi đã phải đối mặt với một số scnarios giống như ví dụ nơi mà tôi muốn sử dụng một ternary, nhưng kết thúc lặp lại :(
user1354934

1
Ở ví dụ đầu tiên, làm thế nào để chúng tôi xác định rằng có 3hoặc "y"không ở chỉ mục 0của someArray?
271314

Trên Math.maxví dụ? indexOftrả về chỉ số của phần tử và nếu phần tử không được tìm thấy thì trả về -1 vì vậy bạn có cơ hội nhận được một số từ -1 đến độ dài của chuỗi, sau đó Math.maxbạn chỉ cần đặt các ranh giới từ 0 đến độ dài để loại bỏ cơ hội để trả về -1,
Crisoforo Gaspar

@mitogh Logic tại mã tại OP tạo ra một vấn đề, ví dụ chung chung là như vậy; trong đó 0 có thể chỉ ra chỉ số 0của phần tử phù hợp trong mảng hoặc 0được đặt tại Math.max(); hoặc tại toán tử có điều kiện tại OP. Hãy cân nhắc var value = Math.max( ["y"].indexOf("y"), 0 ). Làm thế nào để bạn xác định cái nào 0đang được trả lại? 0được truyền để Math.max()gọi, hoặc 0phản ánh chỉ số của "y"bên trong mảng?
271314

@ guest271314 Ý kiến ​​hay đấy, nhưng tôi nghĩ nó phụ thuộc vào ngữ cảnh xem đó có phải là vấn đề hay không. Có lẽ không quan trọng số 0 đến từ đâu, và điều quan trọng duy nhất là nó không phải -1. Ví dụ: có thể bạn cần chọn một mục từ một mảng. Bạn muốn một mục cụ thể (trong OP, số 3), nhưng nếu đó không có trong mảng, bạn vẫn cần một mục và bạn ổn với việc đặt mặc định cho mục đầu tiên là gì, giả sử bạn biết mảng là không t rỗng.
Kev

27

Không thực sự, chỉ cần sử dụng một biến khác.

Ví dụ của bạn khái quát thành một cái gì đó như thế này.

var x = predicate(f()) ? f() : default;

Bạn đang kiểm tra một giá trị được tính toán, sau đó gán giá trị đó cho một biến nếu nó chuyển một số vị từ. Cách để tránh tính lại giá trị đã tính là hiển nhiên: sử dụng một biến để lưu trữ kết quả.

var computed = f();
var x = predicate(computed) ? computed : default;

Tôi hiểu ý bạn - có vẻ như cần phải có một số cách để làm điều này trông gọn gàng hơn một chút. Nhưng tôi nghĩ đó là cách tốt nhất (nói một cách thành ngữ) để làm điều này. Nếu bạn đang lặp lại nhiều lần mẫu này trong mã của mình vì lý do nào đó, bạn có thể viết một hàm trợ giúp nhỏ:

var setif = (value, predicate, default) => predicate(value) ? value : default;
var x = setif(someArray.indexOf(3), x => x !== -1, 0)

17

CHỈNH SỬA: Đây rồi, đề xuất cho liên kết Nullary ngay bây giờ trong JavaScript!


Sử dụng ||

const result = a ? a : 'fallback value';

tương đương với

const result = a || 'fallback value';

Nếu truyền ađể Booleantrả về false, resultsẽ được gán 'fallback value', nếu không giá trị của a.


Hãy lưu ý đến trường hợp cạnh a === 0, sẽ diễn ra falseresultsẽ (không chính xác) lấy 'fallback value'. Sử dụng các thủ thuật như thế này có nguy cơ của riêng bạn.


Tái bút. Các ngôn ngữ như Swift có toán tử liên kết nil ( ??), phục vụ mục đích tương tự. Ví dụ, trong Swift, bạn sẽ viết result = a ?? "fallback value"nó khá gần với JavaScriptconst result = a || 'fallback value';


3
PHP (> 7.0) và C # cũng hỗ trợ toán tử kết hợp rỗng. Đường tổng hợp nhưng chắc chắn đáng yêu.
Hissvard

5
Điều này chỉ hoạt động khi hàm trả về giá trị falsey khi nó bị lỗi, nhưng indexOf()không thể được sử dụng trong mẫu này.
Barmar

1
Đúng, nhưng anh ấy không yêu cầu ví dụ cụ thể> "Một lần nữa, không tìm kiếm câu trả lời cho câu hỏi chính xác ở trên, chỉ là một ví dụ về thời điểm bạn có thể lặp lại những điều trong thuật ngữ ba" <, nhớ bạn là anh ấy đang yêu cầu một cách chung chung để thay thế bậc ba lặp lại (kết quả = a? a: b). Và bậc ba lặp lại tương đương với || (result = a || b)
Lyubomir

2
Đó có thực sự là cách ||hoạt động trong JavaScript không? Nếu tôi hiểu bạn chính xác, thì nó hoạt động khác với nhiều ngôn ngữ chính khác (tôi chủ yếu nghĩ về C và con cháu của nó [C ++, Java, v.v.]) Ngay cả khi đó thực sự là cách ||hoạt động trong JavaScript, tôi khuyên bạn không nên sử dụng những thủ thuật như thế này đòi hỏi người bảo trì phải biết những điều đặc biệt về ngôn ngữ. Mặc dù thủ thuật đó rất hay, nhưng tôi sẽ coi đó là một hành động xấu.
Loduwijk

1
Cũng lưu ý rằng câu hỏi đang so sánh giá trị với -1. Một lần nữa, tôi không thể nói về JavaScript và những điều kỳ quặc của nó, nhưng nói chung -1sẽ là một giá trị đúng, không phải là một giá trị sai, và do đó câu trả lời của bạn sẽ không hoạt động trong trường hợp của câu hỏi và chắc chắn không phải trường hợp chung, thay vì chỉ hoạt động trong một trường hợp cụ thể ( nhưng đủ phổ biến) trường hợp phụ.
Loduwijk

8

Sử dụng cấu trúc lại biến trích xuất :

var index = someArray.indexOf(3);
var value = index !== -1 ? index : 0

Nó thậm chí còn tốt hơn với constthay vìvar . Bạn cũng có thể thực hiện một trích xuất bổ sung:

const index = someArray.indexOf(3);
const condition = index !== -1;
const value = condition ? index : 0;

Trên thực tế, sử dụng tên có ý nghĩa hơn index, conditionvalue.

const threesIndex = someArray.indexOf(3);
const threeFound = threesIndex !== -1;
const threesIndexOrZero = threeFound ? threesIndex : 0;

"Biến trích xuất" là gì? Đó có phải là một thuật ngữ được thiết lập không?
Peter Mortensen

6

Có thể bạn đang tìm kiếm một nhà điều hành liên kết. May mắn thay, chúng tôi có thể tận dụng Arraynguyên mẫu để tạo ra:

Array.prototype.coalesce = function() {
    for (var i = 0; i < this.length; i++) {
        if (this[i] != false && this[i] != null) return this[i];
    }
}

[null, false, 0, 5, 'test'].coalesce(); // returns 5

Điều này có thể được tổng quát hóa thêm cho trường hợp của bạn, bằng cách thêm một tham số vào hàm:

Array.prototype.coalesce = function(valid) {
    if (typeof valid !== 'function') {
        valid = function(a) {
            return a != false && a != null;
        }
    }

    for (var i = 0; i < this.length; i++) {
        if (valid(this[i])) return this[i];
    }
}

[null, false, 0, 5, 'test'].coalesce(); // still returns 5
[null, false, 0, 5, 'test'].coalesce(function(a){return a !== -1}); // returns null
[null, false, 0, 5, 'test'].coalesce(function(a){return a != null}); //returns false

Việc thêm vào nguyên mẫu của mảng là rất rủi ro, vì phần tử mới sẽ trở thành chỉ mục bên trong mọi mảng. Điều này có nghĩa rằng iterating thông qua các chỉ số cũng bao gồm các phương pháp mới: for (let x in ['b','c']) console.log(x);in 0, 1, "coalesce".
Charlie Harding

@CharlieHarding Đúng, nhưng thường không nên sử dụng toán tử for-in khi lặp qua các mảng. Xem stackoverflow.com/a/4374244/1486100
Tyzoid

6

Cá nhân tôi thích hai biến thể:

  1. Thuần túy nếu, như @slebetman đề xuất

  2. Hàm tách biệt, thay thế giá trị không hợp lệ bằng giá trị mặc định, như trong ví dụ sau:

function maskNegative(v, def) {
  return v >= 0 ? v : def;
}

Array.prototype.indexOfOrDefault = function(v, def) {
  return maskNegative(this.indexOf(v), def);
}

var someArray = [1, 2];
console.log(someArray.indexOfOrDefault(2, 0)); // index is 1
console.log(someArray.indexOfOrDefault(3, 0)); // default 0 returned
console.log(someArray.indexOfOrDefault(3, 123)); // default 123 returned


1
+1, tùy chọn 2 tôn trọng mục đích nội tuyến của câu hỏi, có thể áp dụng hiệu quả cho các ngôn ngữ khác ngoài javascript và thúc đẩy tính mô-đun.
Devsman

5

Tôi thích câu trả lời của @ slbetman. Bình luận dưới đó bày tỏ lo lắng về việc biến đang ở "trạng thái trung gian". nếu đây là một mối quan tâm lớn đối với bạn thì tôi khuyên bạn nên gói gọn nó trong một hàm:

function get_value(arr) {
   var value = arr.indexOf(3);
   if (value === -1) {
     value = 0;
   }
   return value;
}

Sau đó chỉ cần gọi

var value = get_value( someArray );

Bạn có thể thực hiện nhiều chức năng chung hơn nếu bạn sử dụng chúng ở những nơi khác, nhưng đừng thiết kế quá mức nếu đó là một trường hợp rất cụ thể.

Nhưng thành thật mà nói, tôi sẽ chỉ làm như @slebetman trừ khi tôi cần sử dụng lại từ một số nơi.


4

Có hai cách tôi có thể thấy khi xem xét câu hỏi của bạn: bạn muốn giảm độ dài dòng hoặc bạn muốn tránh lặp lại một biến trong một số ba. Đầu tiên là tầm thường (và nhiều người dùng khác đã đăng ví dụ):

var value = someArray.indexOf(3) !== -1 ? someArray.indexOf(3) : 0;

có thể được (và nên được, với các lệnh gọi hàm) được rút gọn như vậy:

var value = someArray.indexOf(3);
value = value !== -1 ? value : 0;

Nếu bạn đang tìm kiếm một giải pháp chung chung hơn để ngăn chặn sự lặp lại của một biến trong một bậc ba, như sau:

var value = conditionalTest(foo) ? foo : bar;

nơi foochỉ xuất hiện một lần. Loại bỏ các giải pháp của biểu mẫu:

var cad = foo;
var value = conditionalTest(foo) ? cad : bar;

đúng kỹ thuật nhưng thiếu điểm, thì bạn đã hết may mắn. Có các toán tử, hàm và phương thức sở hữu cú pháp ngắn gọn mà bạn tìm kiếm, nhưng các cấu trúc như vậy, theo định nghĩa, không phải là toán tử bậc ba .

Ví dụ:

javascript, sử dụng ||để trả về RHS khi LHS là falsey:

var value = foo || bar; // equivalent to !foo ? bar : foo

1
Câu hỏi được gắn thẻ javascript và không đề cập đến C #. Chỉ tự hỏi tại sao bạn lại kết thúc bằng các ví dụ cụ thể của C #.
Loduwijk

Tôi đã bỏ lỡ thẻ javascript trên câu hỏi; đã loại bỏ C #.
asgallant

3

Sử dụng một chức năng trợ giúp:

function translateValue(value, match, translated) {
   return value === match ? translated : value;
}

Bây giờ mã của bạn rất dễ đọc và không có sự lặp lại.

var value = translateValue(someArray.indexOf(3), -1, 0);

Thứ bậc của các mối quan tâm về mã hóa là:

  1. Đúng (bao gồm hiệu suất thực sự hoặc các mối quan tâm về SLA)
  2. Thông thoáng
  3. Ngắn gọn
  4. Nhanh

Tất cả các câu trả lời trên trang cho đến nay đều có vẻ đúng, nhưng tôi nghĩ phiên bản của tôi có độ rõ ràng cao nhất, điều này quan trọng hơn tính ngắn gọn. Nếu bạn không tính hàm trợ giúp — vì nó có thể được sử dụng lại — thì đó cũng là hàm ngắn gọn nhất. Đề xuất hơi tương tự để sử dụng một hàm trợ giúp không may lại sử dụng lambda mà đối với tôi, chỉ che khuất những gì nó đang làm. Đối với tôi, một hàm đơn giản hơn với một mục đích không sử dụng lambda, chỉ sử dụng các giá trị.

PS Nếu bạn thích cú pháp ES6:

const translateValue = (value, match, translated) => value === match ? translated : value;
let value = translateValue(someArray.indexOf(3), -1, 0); // or const

2
"phiên bản của tôi có độ rõ ràng cao nhất" - Tôi không đồng ý. Tên hàm quá dài và việc đặt tên tham số đầu vàođầu ra không hữu ích chút nào.
adelphus

Vậy bạn có thể gợi ý những cái tên hay hơn không? Tôi rất vui khi được giải trí với họ. Khiếu nại của bạn chỉ là về mỹ phẩm, vì vậy chúng ta hãy sửa chữa mỹ phẩm. Đúng? Nếu không, bạn chỉ là đổ xe đạp.
ErikE

Trong một số trường hợp, một chức năng trợ giúp như vậy có thể hữu ích. Trong trường hợp này, khi nó chỉ thay thế một trường hợp cụ thể của toán tử bậc ba, chức năng của bạn sẽ kém rõ ràng hơn. Tôi sẽ không nhớ chức năng của bạn làm gì, và tôi sẽ phải tra cứu lại mỗi khi tôi bắt gặp nó, và tôi sẽ không bao giờ nhớ sử dụng nó.
Loduwijk

1
@Aaron Đó là một đánh giá hợp lý cho một trường hợp sử dụng cụ thể. Đối với những gì nó đáng giá, tên chức năng ban đầu của tôi translateValueIfEqualmà tôi nghĩ là mô tả hơn, nhưng tôi đã thay đổi nó sau khi ai đó cho rằng nó quá lâu. Cũng giống như Nzchức năng trong Access, nếu bạn biết nó, bạn biết nó, và nếu bạn không biết thì bạn không biết. Trong IDE hiện đại, bạn có thể chỉ cần nhấn một phím để chuyển đến định nghĩa. Và dự phòng sẽ là biến trung gian. Tôi không thực sự thấy một khía cạnh lớn ở đây.
ErikE

1
Điều này chỉ ra rằng nếu bạn hỏi cùng một câu hỏi cho 5 kỹ sư khác nhau, bạn sẽ nhận được 10 câu trả lời khác nhau.
Loduwijk

2

Tôi nghĩ rằng ||nhà điều hành có thể được điều chỉnh để indexOf:

var value = ((someArray.indexOf(3) + 1) || 1) - 1;

Giá trị trả về được dịch chuyển lên 1, tạo thành 0 từ -1, giá trị này là sai và do đó được thay thế bằng giá trị thứ hai 1. Sau đó, nó được chuyển ngược lại.

Tuy nhiên, hãy nhớ rằng khả năng đọc tốt hơn việc tránh lặp lại.


2

Đây là một giải pháp đơn giản với KHÔNG theo bit và một giá trị mặc định -1mà kết quả sau đó là 0.

index = ~(~array.indexOf(3) || -1);

Về cơ bản, nó hoạt động với hàm NOT bit theo chiều kép, trả về giá trị ban đầu hoặc giá trị mặc định, sau khi áp dụng bitwise NOT sẽ trả về 0.

Hãy xem bảng sự thật:

 indexOf    ~indexOf   boolean    default     value      result         comment
---------  ---------  ---------  ---------  ---------  ---------  ------------------
      -1          0     falsy          -1         -1          0   take default value
       0         -1    truthy                     -1          0
       1         -2    truthy                     -2          1
       2         -3    truthy                     -3          2

0

Bạn có thể sử dụng phân công lại:

  • khởi tạo biến thành một giá trị
  • sử dụng tuần tự hóa &&toán tử để gán lại, bởi vì nếu điều kiện đầu tiên là sai, biểu thức thứ hai sẽ không được đánh giá

Ví dụ.

var value = someArray.indexOf(3);
value == -1 && (value=0);


3
@MinusFour Ở một mức độ. Biến được lặp lại, không phải biểu thức someArray.indexOfchỉ được thực hiện một lần
vol7ron 12/04/2017

Bạn lặp lại value.
Minus

3
@MinusFour Đúng, nhưng điều này hữu ích hơn cho các biểu thức lớn hơn, việc lặp lại một biến là không đáng kể so với việc lưu các hoạt động. Tôi đoán là OP không hoạt động với -10; nếu không thì max()sẽ là lựa chọn tốt nhất
vol7ron

2
Đúng ... nhưng câu hỏi là ... "Làm thế nào để viết các cụm từ mà không lặp lại chính mình"
MinusFour

4
Nó cũng nói Again, not seeking an answer to the exact question above, điều này khiến câu hỏi phải giải thích;)
vol7ron

0

Đưa ra mã ví dụ tại Câu hỏi, không rõ làm thế nào nó sẽ được xác định rằng 3được hoặc không được đặt ở chỉ mục 0của someArray. -1trả về từ .indexOf()sẽ có giá trị trong trường hợp này, với mục đích loại trừ trường hợp không khớp được cho là có thể là một kết quả trùng khớp.

Nếu 3không được bao gồm trong mảng, -1sẽ được trả về. Chúng ta có thể thêm 1vào kết quả của .indexOf()để đánh giá falsekết quả như thế nào -1, theo sau là || ORtoán tử và 0. Khi valueđược tham chiếu, hãy trừ đi 1để nhận chỉ số của phần tử của mảng hoặc -1.

Dẫn đến việc chỉ cần sử dụng .indexOf()và kiểm tra -1tại một ifđiều kiện. Hoặc định valuenhư undefinedđể tránh có thể nhầm lẫn về thực tế kết quả của tình trạng đánh giá liên quan đến tài liệu tham khảo ban đầu.

var someArray = [1,2,3];
var value = someArray.indexOf(3) + 1 || 1;
console.log(value -= 1);

var someArray = [1,2,3];
var value = someArray.indexOf(4) + 1 || 1;
// how do we know that `4` is not at index `0`?
console.log(value -= 1);

var someArray = [1,2,3];
var value = someArray.indexOf(4) + 1 || void 0;
// we know for certain that `4` is not found in `someArray`
console.log(value, value = value || 0);


0

Một con ba giống như một if-else, nếu bạn không cần phần khác, tại sao không chỉ một if thay vào đó ..

if ((value = someArray.indexOf(3)) < 0) value = 0;

0

Đối với trường hợp cụ thể này, bạn có thể sử dụng đoản mạch với ||toán tử logic . Vì 0được coi là sai, bạn có thể thêm 1vào chỉ mục của mình, do đó, nếu index+10thì bạn sẽ nhận được phía bên phải của logic-hoặc kết quả của bạn, nếu không, bạn sẽ nhận được index+1. Vì kết quả mong muốn của bạn được bù đắp bởi 1, sau đó bạn có thể trừ đi 1để nhận chỉ mục của mình:

const someArray = [1, 2, 3, 4];
const v = ((someArray.indexOf(3)+1) || 1)-1;
console.log(v);

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.