แปลงผลลัพธ์บูลีนเป็นตัวเลข / จำนวนเต็ม


276

ฉันมีตัวแปรที่เก็บfalseหรือtrueแต่ฉันต้องการ0หรือ1แทนตามลำดับ ฉันจะทำสิ่งนี้ได้อย่างไร


8
นี่คือการเปรียบเทียบประสิทธิภาพการทำงานของบางส่วนของเทคนิคที่ให้: jsperf.com/conversion-from-boolean-to-number
Sam

4
ผู้ใช้Node.JSจะต้องการใช้bool === true ? 1 : 0เนื่องจากเป็นรุ่นที่เร็วที่สุดใน V8
Qix - MONICA ถูกยกเลิก

3
หรือเพียงแค่bool ? 1 : 0;
Atrahasis

คำตอบ:


343

Javascript มีผู้ประกอบการที่คุณสามารถใช้:

var i = result ? 1 : 0;

7
คำตอบที่ดีที่สุด ทำไม? งานนี้บน truthiness ซึ่งเป็นทั่วไปมากขึ้นและยอมรับชนิดใด ๆ (สตริงจำนวน etcetera.) คำตอบเอกเป็นคนฉลาดจริง NaNแต่ถ้าผมผ่านมันสตริงผลตอบแทน ดังนั้นหากคุณต้องการ L33T และรับประกันอินพุตให้ไปที่ทางเดินปัสสาวะไม่เช่นนั้นการทดสอบแบบไตรภาค + ความจริงก็ดีที่สุด
gdibble

465

ใช้โอเปอเรเตอร์unary+ซึ่งแปลงตัวถูกดำเนินการเป็นตัวเลข

+ true; // 1
+ false; // 0

หมายเหตุแน่นอนว่าคุณควรจะยังคงฆ่าเชื้อข้อมูลในฝั่งเซิร์ฟเวอร์เนื่องจากผู้ใช้สามารถส่งข้อมูลใด ๆ ไปยังเซิร์ฟเวอร์ของคุณได้ไม่ว่ารหัสฝั่งไคลเอ็นต์จะพูดอะไร


50
แม้ว่าจะยอดเยี่ยม (ฉันไม่เคยคิดมาก่อน) มันช้าอย่างไม่น่าเชื่อ (Chrome ทำงานช้าลง 97%) ระวังตัวด้วย!
Qix - MONICA ถูกยกเลิกเมื่อ

5
ตรวจสอบการแก้ไขนี้ Number()ช้ากว่า
Qix - MONICA ถูกยกเลิกเมื่อ

23
แต่ดูเหมือนว่ามันเป็นวิธีที่เร็วด้วยสองใกล้ชิดจากbool === true ? 1 : 0 bool | 0
Qix - MONICA ได้รับการยกเว้นเมื่อ

1
การคูณ (เช่น 3 * false) รู้สึกผิด แต่มันได้ผล :) ขอบคุณ!
mattsoave

1
@DerkJanSpeelman ความจริงที่ว่าสิ่งที่ไม่ได้รับอนุญาตใน typescript ไม่ได้หมายความว่าคุณไม่ควรทำใน Javascript พวกเขามีภาษาที่แตกต่างกัน (แม้ว่าจะเกี่ยวข้อง)
lonesomeday

119

Imho ทางออกที่ดีที่สุดคือ:

fooBar | 0

ใช้ใน asm.js เพื่อบังคับประเภทจำนวนเต็ม


เร็วที่สุด; +1
Qix - MONICA ถูกยกเลิกเมื่อ

3
ทำได้ดีนี่. นอกจากนี้คุณสามารถใช้ "Boolean ^ 0" OR หรือ XOR ทำงาน
F8ER

สิ่งนี้จะไม่คืน1ค่าจำนวนเต็มหาก fooBar ไม่ใช่หรือ
ESR

58

ฉันชอบที่จะใช้ฟังก์ชั่นจำนวน ใช้วัตถุและแปลงเป็นตัวเลข

ตัวอย่าง:

var myFalseBool = false;
var myTrueBool = true;

var myFalseInt = Number(myFalseBool);
console.log(myFalseInt === 0);

var myTrueInt = Number(myTrueBool);
console.log(myTrueInt === 1);

คุณสามารถทดสอบได้ในjsFiddle


3
นี่คือคำตอบที่ดีที่สุด ที่ด้านล่างแน่นอน เฉพาะ "ใช้วัตถุ" ไม่ถูกต้อง
Rudie

2
ลิงก์ไปยัง mdn นั้นดีกว่า w3schools (eeek!): developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
......

ฉันคิดว่านี่เป็นวิธีที่ดีที่สุดเพราะง่ายต่อการอ่านและเปิดเผยความตั้งใจ
Sam

3
นอกจากนี้ยังเป็นช้าที่สุด
Qix - MONICA ถูกยกเลิก

45

ฉันสร้างการเปรียบเทียบJSperfของคำตอบที่แนะนำทั้งหมด

TL; DR - ตัวเลือกที่ดีที่สุดสำหรับเบราว์เซอร์ปัจจุบันทั้งหมดคือ:

val | 0;

.

ปรับปรุง:

ดูเหมือนว่าวันนี้พวกเขาทั้งหมดเหมือนกันสวยยกเว้นว่าฟังก์ชั่นที่ช้าที่สุดในขณะที่ความเป็นอยู่ที่ดีที่สุดNumber()val === true ? 1 : 0;


2
สิ่งที่น่าสนใจคือ ternary นั้นเร็วที่สุดใน Chrome 64.0.3282 บน macOS 10.13.3
2540625

นั่นจะเป็นตัวเลือกที่เร็วที่สุดในเวลานั้น ที่แตกต่างจากมันเป็นตัวเลือกที่ดีที่สุด
mikemaccana


30

ฉันเพิ่งเจอทางลัดนี้วันนี้

~~ (จริง)

~~ (เท็จ)

ผู้คนฉลาดกว่าที่ฉันจะอธิบายได้:

http://james.padolsey.com/javascript/double-bitwise-not/


2
น่าสนใจ ฉันเรียนรู้สิ่งใหม่วันนี้ ฉันจะไม่ใช้เทคนิคนี้ในโครงการใด ๆ เพราะมีความเป็นไปได้ที่จะสร้างความสับสนในอนาคตฉันหรือเพื่อนร่วมทีม
nicholaides

1
แฮกเกอร์ js เป็นที่โปรดปรานของฉัน อย่างจริงจัง +1
ทอดด์

16

เมื่อ JavaScript คาดว่าจะมีค่าตัวเลข แต่จะได้รับบูลีนแทนมันจะแปลงบูลีนนั้นเป็นตัวเลข: การแปลงจริงและเท็จเป็น 1 และ 0 ตามลำดับ ดังนั้นคุณสามารถใช้ประโยชน์จากสิ่งนี้;

var t = true;
var f = false;

console.log(t*1); // t*1 === 1
console.log(f*1); // f*1 === 0 

console.log(+t); // 0+t === 1 or shortened to +t === 1
console.log(+f); //0+f === 0 or shortened to +f === 0

การอ่านเพิ่มเติมประเภทการแปลงบทที่ 3.8 ของคู่มือสรุปสำหรับ Javascript


13

+ผู้ประกอบการเอกจะดูแลเรื่องนี้:

var test = true;
// +test === 1
test = false;
// +test === 0

โดยปกติคุณจะต้องมีสติ - ตรวจสอบสิ่งนี้บนเซิร์ฟเวอร์ก่อนที่จะเก็บไว้เพื่อที่จะเป็นสถานที่ที่เหมาะสมในการทำเช่นนี้


ฉันมีการเปลี่ยนแปลงการแสดงความคิดเห็นไป===เพราะtrue == 1เป็นจริงแม้โดยไม่ต้อง "การแปลงอย่างชัดเจน :-) true === 1แทนที่จะเป็นเท็จ.
Xanatos

13

ฉันเพิ่งจะจัดการกับปัญหานี้ในบางรหัสที่ฉันเขียน ทางออกของฉันคือการใช้ระดับบิตและ

var j = bool & 1;

วิธีที่รวดเร็วกว่าในการจัดการกับปัญหาคงที่คือการสร้างฟังก์ชั่น คนอื่นสามารถอ่านได้มากขึ้นเข้าใจในขั้นตอนการบำรุงรักษาได้ดีขึ้นและกำจัดโอกาสในการเขียนสิ่งที่ผิด

function toInt( val ) {
    return val & 1;
}

var j = toInt(bool);

แก้ไข - 10 กันยายน 2014

ไม่มีการแปลงโดยใช้โอเปอเรเตอร์ที่ประกอบไปด้วยที่เหมือนกันกับโอเปอเรเตอร์ใน Chrome เร็วกว่าด้วยเหตุผลบางประการ ไม่สมเหตุสมผลว่าทำไมมันถึงเร็วกว่านี้ แต่ฉันคิดว่ามันเป็นการเพิ่มประสิทธิภาพระดับต่ำที่เหมาะสมในบางที่ตลอดทาง

var j = boolValue === true ? 1 : 0;

ทดสอบด้วยตัวเอง: http://jsperf.com/boolean-int-conversion/2

ใน FireFox และ Internet Explorer การใช้รุ่นที่ฉันโพสต์นั้นเร็วกว่าปกติ

แก้ไข - 14 กรกฎาคม 2017

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

นอกจากนี้ต่อไปนี้เป็นวิธีการใหม่สำหรับการเพิ่มต้นแบบ 'toInt' ที่ไม่สามารถเขียนทับได้

Object.defineProperty(Boolean.prototype, "toInt", { value: function()
{
    return this & 1;
}});

ฉันมีสอง downvotes สำหรับโพสต์นี้ ทำไมคุณไม่อธิบายว่าทำไมคุณถึงลงคะแนน มิฉะนั้นมันเป็นเพียง downvote โดยไม่มีเหตุผล
Nicholas R. Grant

1
99 ครั้งผลลัพธ์ของ jsperf เพียงนำคุณสู่เส้นทางการปรับให้เหมาะสมก่อนกำหนดเพิ่มประสิทธิภาพ nanoseconds ปิดลูปเมื่อคุณควรเพ่งความสนใจไปที่คำสั่ง SQL ที่น่าเกลียดแทน ขอขอบคุณที่ให้วิธีการต่าง ๆ ในการเข้าถึงสิ่งนี้
RozzA

คำสั่ง SQL อะไร? ไม่มีแบบสอบถามเดียวที่นี่ หากคุณอ้างถึง JSPerf ฉันกำลังเชื่อมโยงสิ่งนั้นกับการทดสอบของคนอื่น มันไม่ใช่ของฉันเอง ฉันไม่สนใจเกี่ยวกับแง่มุมการแสดงอย่างนี้เพราะมันไม่มีอะไรดำเนินการ ฉันสร้างภาษาของตัวเองซึ่งเกือบจะใช้งานได้เหมือนกับ JS และฉันจำได้ว่าการใช้งาน int นั้นเป็นการทำงานที่รวดเร็วอย่างน่างงงวย โซ่ปีนเขาต้นแบบไม่ได้ นี่คือเหตุผลที่ฉันยังคงแนะนำวิธีแรกที่ฉันทำได้โดยมีฟังก์ชั่นเรียบง่ายที่สามารถคอมไพล์ได้
Nicholas R. Grant

สิ่ง SQL 'เป็นการทั่วไป ขอบคุณสำหรับข้อมูลเชิงลึก
RozzA

9

คุณยังสามารถเพิ่ม 0 ใช้ตัวดำเนินการ shift หรือ xor:

val + 0;
val ^ 0;
val >> 0;
val >>> 0;
val << 0;

สิ่งเหล่านี้มีความเร็วใกล้เคียงกับคำตอบจากคนอื่น


6

ในบริบทของฉัน React Native ที่ฉันได้รับค่าความทึบจากบูลีนวิธีที่ง่ายที่สุด: ใช้ตัวดำเนินการ unary +

+ true; // 1
+ false; // 0

นี่จะแปลงบูลีนเป็นตัวเลข

style={ opacity: +!isFirstStep() }

4

คุณสามารถทำได้โดยเพียงแค่ขยายบูลีนต้นแบบ

Boolean.prototype.intval = function(){return ~~this}

มันไม่ง่ายเกินไปที่จะเข้าใจว่าเกิดอะไรขึ้นที่นั่นดังนั้นจะมีรุ่นอื่น

Boolean.prototype.intval = function(){return (this == true)?1:0}

เมื่อทำเสร็จแล้วคุณสามารถทำสิ่งต่าง ๆ เช่น

document.write(true.intval());

เมื่อฉันใช้ booleans เพื่อเก็บเงื่อนไขฉันมักจะแปลงให้เป็น bitfields ซึ่งในกรณีนี้ฉันใช้ฟังก์ชันต้นแบบรุ่นขยาย

Boolean.prototype.intval = function(places)
{
 places = ('undefined' == typeof(places))?0:places; 
 return (~~this) << places
}

ด้วยสิ่งที่คุณสามารถทำได้

document.write(true.intval(2))

ซึ่งสร้าง 4 เป็นเอาท์พุท




1

ฉันได้ทดสอบตัวอย่างทั้งหมดนี้แล้วฉันได้ทำการวัดประสิทธิภาพและในที่สุดฉันขอแนะนำให้คุณเลือกอันที่สั้นกว่านี้ซึ่งจะไม่ส่งผลต่อประสิทธิภาพการทำงาน

รันในเซิร์ฟเวอร์ Ubuntu 14.04, nodejs v8.12.0 - 26/10/18

    let i = 0;
console.time("TRUE test1")
    i=0;
    for(;i<100000000;i=i+1){
        true ? 1 : 0;
    }
console.timeEnd("TRUE test1")


console.time("FALSE test2")
    i=0;
    for(;i<100000000;i=i+1){
        false ? 1 : 0;
    }
console.timeEnd("FALSE test2")

console.log("----------------------------")

console.time("TRUE test1.1")
    i=0;
    for(;i<100000000;i=i+1){
        true === true ? 1 : 0;
    }
console.timeEnd("TRUE test1.1")


console.time("FALSE test2.1")
    i=0;
    for(;i<100000000;i=i+1){
        false === true ? 1 : 0;
    }
console.timeEnd("FALSE test2.1")

console.log("----------------------------")

console.time("TRUE test3")
    i=0;
    for(;i<100000000;i=i+1){
        true | 0;
    }
console.timeEnd("TRUE test3")

console.time("FALSE test4")
    i=0;
    for(;i<100000000;i=i+1){
        false | 0;
    }
console.timeEnd("FALSE test4")

console.log("----------------------------")

console.time("TRUE test5")
    i=0;
    for(;i<100000000;i=i+1){
        true * 1;
    }
console.timeEnd("TRUE test5")

console.time("FALSE test6")
    i=0;
    for(;i<100000000;i=i+1){
        false * 1;
    }
console.timeEnd("FALSE test6")

console.log("----------------------------")

console.time("TRUE test7")
    i=0;
    for(;i<100000000;i=i+1){
        true & 1;
    }
console.timeEnd("TRUE test7")

console.time("FALSE test8")
    i=0;
    for(;i<100000000;i=i+1){
        false & 1;
    }
console.timeEnd("FALSE test8")

console.log("----------------------------")

console.time("TRUE test9")
    i=0;
    for(;i<100000000;i=i+1){
        +true;
    }
console.timeEnd("TRUE test9")

console.time("FALSE test10")
    i=0;
    for(;i<100000000;i=i+1){
        +false;
    }
console.timeEnd("FALSE test10")

console.log("----------------------------")

console.time("TRUE test9.1")
    i=0;
    for(;i<100000000;i=i+1){
        0+true;
    }
console.timeEnd("TRUE test9.1")

console.time("FALSE test10.1")
    i=0;
    for(;i<100000000;i=i+1){
        0+false;
    }
console.timeEnd("FALSE test10.1")

console.log("----------------------------")

console.time("TRUE test9.2")
    i=0;
    for(;i<100000000;i=i+1){
        -true*-1;
    }
console.timeEnd("TRUE test9.2")

console.time("FALSE test10.2")
    i=0;
    for(;i<100000000;i=i+1){
        -false*-1;
    }
console.timeEnd("FALSE test10.2")

console.log("----------------------------")

console.time("TRUE test9.3")
    i=0;
    for(;i<100000000;i=i+1){
        true-0;
    }
console.timeEnd("TRUE test9.3")

console.time("FALSE test10.3")
    i=0;
    for(;i<100000000;i=i+1){
        false-0;
    }
console.timeEnd("FALSE test10.3")

console.log("----------------------------")

console.time("TRUE test11")
    i=0;
    for(;i<100000000;i=i+1){
        Number(true);
    }
console.timeEnd("TRUE test11")

console.time("FALSE test12")
    i=0;
    for(;i<100000000;i=i+1){
        Number(false);
    }
console.timeEnd("FALSE test12")

console.log("----------------------------")

console.time("TRUE test13")
    i=0;
    for(;i<100000000;i=i+1){
        true + 0;
    }
console.timeEnd("TRUE test13")

console.time("FALSE test14")
    i=0;
    for(;i<100000000;i=i+1){
        false + 0;
    }
console.timeEnd("FALSE test14")

console.log("----------------------------")

console.time("TRUE test15")
    i=0;
    for(;i<100000000;i=i+1){
        true ^ 0;
    }
console.timeEnd("TRUE test15")

console.time("FALSE test16")
    i=0;
    for(;i<100000000;i=i+1){
        false ^ 0;
    }
console.timeEnd("FALSE test16")

console.log("----------------------------")

console.time("TRUE test17")
    i=0;
    for(;i<100000000;i=i+1){
        true ^ 0;
    }
console.timeEnd("TRUE test17")

console.time("FALSE test18")
    i=0;
    for(;i<100000000;i=i+1){
        false ^ 0;
    }
console.timeEnd("FALSE test18")

console.log("----------------------------")

console.time("TRUE test19")
    i=0;
    for(;i<100000000;i=i+1){
        true >> 0;
    }
console.timeEnd("TRUE test19")

console.time("FALSE test20")
    i=0;
    for(;i<100000000;i=i+1){
        false >> 0;
    }
console.timeEnd("FALSE test20")

console.log("----------------------------")

console.time("TRUE test21")
    i=0;
    for(;i<100000000;i=i+1){
        true >>> 0;
    }
console.timeEnd("TRUE test21")

console.time("FALSE test22")
    i=0;
    for(;i<100000000;i=i+1){
        false >>> 0;
    }
console.timeEnd("FALSE test22")

console.log("----------------------------")

console.time("TRUE test23")
    i=0;
    for(;i<100000000;i=i+1){
        true << 0;
    }
console.timeEnd("TRUE test23")

console.time("FALSE test24")
    i=0;
    for(;i<100000000;i=i+1){
        false << 0;
    }
console.timeEnd("FALSE test24")

console.log("----------------------------")

console.time("TRUE test25")
    i=0;
    for(;i<100000000;i=i+1){
        ~~true;
    }
console.timeEnd("TRUE test25")

console.time("FALSE test26")
    i=0;
    for(;i<100000000;i=i+1){
        ~~false;
    }
console.timeEnd("FALSE test26")

console.log("----------------------------")

console.time("TRUE test25.1")
    i=0;
    for(;i<100000000;i=i+1){
        ~true*-1-1;
    }
console.timeEnd("TRUE test25.1")

console.time("FALSE test26.1")
    i=0;
    for(;i<100000000;i=i+1){
        ~false*-1-1;
    }
console.timeEnd("FALSE test26.1")

console.log("----------------------------")

console.time("TRUE test27")
    i=0;
    for(;i<100000000;i=i+1){
        true/1;
    }
console.timeEnd("TRUE test27")

console.time("FALSE test28")
    i=0;
    for(;i<100000000;i=i+1){
        false/1;
    }
console.timeEnd("FALSE test28")

ผลลัพธ์

TRUE test1: 93.301ms
FALSE test2: 102.854ms
----------------------------
TRUE test1.1: 118.979ms
FALSE test2.1: 119.061ms
----------------------------
TRUE test3: 97.265ms
FALSE test4: 108.389ms
----------------------------
TRUE test5: 85.854ms
FALSE test6: 87.449ms
----------------------------
TRUE test7: 83.126ms
FALSE test8: 84.992ms
----------------------------
TRUE test9: 99.683ms
FALSE test10: 87.080ms
----------------------------
TRUE test9.1: 85.587ms
FALSE test10.1: 86.050ms
----------------------------
TRUE test9.2: 85.883ms
FALSE test10.2: 89.066ms
----------------------------
TRUE test9.3: 86.722ms
FALSE test10.3: 85.187ms
----------------------------
TRUE test11: 86.245ms
FALSE test12: 85.808ms
----------------------------
TRUE test13: 84.192ms
FALSE test14: 84.173ms
----------------------------
TRUE test15: 81.575ms
FALSE test16: 81.699ms
----------------------------
TRUE test17: 81.979ms
FALSE test18: 81.599ms
----------------------------
TRUE test19: 81.578ms
FALSE test20: 81.452ms
----------------------------
TRUE test21: 115.886ms
FALSE test22: 88.935ms
----------------------------
TRUE test23: 82.077ms
FALSE test24: 81.822ms
----------------------------
TRUE test25: 81.904ms
FALSE test26: 82.371ms
----------------------------
TRUE test25.1: 82.319ms
FALSE test26.1: 96.648ms
----------------------------
TRUE test27: 89.943ms
FALSE test28: 83.646ms

0

ถ้าคุณต้องการเปลี่ยนค่าจำนวนเต็ม x ถ้า 1 เป็น 0 และถ้า 0 เป็น 1 คุณสามารถใช้ (x + 1)% 2

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