การทดสอบว่าค่าแปลกหรือแม้แต่


173

ฉันตัดสินใจที่จะสร้างฟังก์ชั่นisEvenและisOddอย่างง่ายด้วยอัลกอริทึมที่ง่ายมาก:

function isEven(n) {
  n = Number(n);
  return n === 0 || !!(n && !(n%2));
}

function isOdd(n) {
  return isEven(Number(n) + 1);
}

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

// Returns true if:
//
//    n is an integer that is evenly divisible by 2
//
// Zero (+/-0) is even
// Returns false if n is not an integer, not even or NaN
// Guard against empty string

(function (global) {

  function basicTests(n) {

    // Deal with empty string
    if (n === '') 
      return false;

    // Convert n to Number (may set to NaN)
    n = Number(n);

    // Deal with NaN
    if (isNaN(n)) 
      return false;

    // Deal with infinity - 
    if (n === Number.NEGATIVE_INFINITY || n === Number.POSITIVE_INFINITY)
      return false;

    // Return n as a number
    return n;
  }

  function isEven(n) {

    // Do basic tests
    if (basicTests(n) === false)
      return false;

    // Convert to Number and proceed
    n = Number(n);

    // Return true/false
    return n === 0 || !!(n && !(n%2));
  }
  global.isEven = isEven;

  // Returns true if n is an integer and (n+1) is even
  // Returns false if n is not an integer or (n+1) is not even
  // Empty string evaluates to zero so returns false (zero is even)
  function isOdd(n) {

    // Do basic tests
    if (basicTests(n) === false)
      return false;

    // Return true/false
    return n === 0 || !!(n && (n%2));
  }
  global.isOdd = isOdd;

}(this));

ทุกคนสามารถเห็นปัญหาใด ๆ กับข้างต้นหรือไม่ มีรุ่นที่ดีกว่า (เช่นแม่นยำยิ่งขึ้นเร็วขึ้นหรือกระชับมากขึ้นโดยไม่ทำให้งง)?

มีโพสต์ต่างๆที่เกี่ยวข้องกับภาษาอื่น ๆ แต่ฉันไม่สามารถหารุ่นที่ชัดเจนสำหรับ ECMAScript


คำตอบ:


368

ใช้โมดูลัส

function isEven(n) {
   return n % 2 == 0;
}

function isOdd(n) {
   return Math.abs(n % 2) == 1;
}

คุณสามารถตรวจสอบว่าค่าใด ๆ ใน Javascript สามารถรวมเข้ากับตัวเลขด้วย:

Number.isFinite(parseFloat(n))

การตรวจสอบนี้ควรทำนอกisEvenและisOddฟังก์ชั่นดังนั้นคุณไม่ต้องทำซ้ำการจัดการข้อผิดพลาดในทั้งสองฟังก์ชั่น


@Steve ใช่ แต่ JS มีปัญหาพิเศษบางอย่างเมื่อvalueไม่ได้เป็นตัวเลขหรือแม้ว่าจะเป็นตัวเลขก็ตาม อดีต .: 0.1%2, NaN%2, []%2ฯลฯ สิ่งที่คุณเขียนไว้ในคำตอบที่เขารู้อยู่แล้วว่ามัน
Alin Purcaru

1
0.1และNaNทำงานได้ดีกับฟังก์ชั่นด้านบน อาร์เรย์ที่ว่างเปล่าเป็นบิตของความเจ็บปวดที่มันเท่ากับ 0 ...
สตีฟเมย์นี

4
@Alin - ฉันได้เพิ่มการตรวจสอบที่เป็นตัวเลข ผมไม่แน่ใจว่าผมเข้าใจสถานการณ์เมื่อคุณต้องการฟังก์ชั่นทางคณิตศาสตร์อย่างชัดเจนจัดการประเภทข้อมูลอื่น ๆ แต่ถ้านั่นคือสิ่ง OP ต้องการ ...
สตีฟเมย์นี

2
เกี่ยวกับการเปลี่ยนreturn n == parseInt(n);เป็นreturn n === parseInt(n);อย่างไร
JiminP

2
ฉันคิดว่าฉันอ่านสิ่งที่คุณควรตรวจสอบn % 2 !== 0เมื่อตรวจสอบตัวเลขคี่เพราะมันไม่จำเป็นต้อง 1 ขึ้นอยู่กับภาษา แก้ไข: อานั่นคือสิ่งที่.absสายสำหรับ ไม่เป็นไรแล้ว
ptf

79

ฉันชอบใช้การทดสอบนิดหน่อย:

if(i & 1)
{
    // ODD
}
else
{
    // EVEN
}

นี่เป็นการทดสอบว่าบิตแรกนั้นอยู่ที่เลขคี่หรือไม่


มีประโยชน์ก็ต่อเมื่อคุณรู้ว่าฉันเป็นตัวเลขที่จะเริ่มต้นด้วย ตัวเลขที่ไม่ใช่ตัวเลขควรส่งคืนโดยไม่ได้กำหนด (หรืออาจเกิดข้อผิดพลาด แต่ไม่ได้กำหนดดูเหมือนจะสมเหตุสมผล)
RobG

3
อย่างแน่นอน การใช้โมดูลัสสำหรับคณิตศาสตร์ฐาน 2 ควรผิดกฎหมาย;)
aceofspades

4
Ternary: i & 1 == 1 ? console.log("odd") : console.log("even");นอกจากนี้ +1 สำหรับประสิทธิภาพระดับบิต (ไม่ได้ใช้กันอย่างแพร่หลายใน JS)
Jacksonkr

13
@Jacksonkr โปรดทราบว่าไม่มี "ประสิทธิภาพระดับบิต" ใน JavaScript เนื่องจากตัวเลขทั้งหมดเป็นแบบลอยใน JavaScript และการใช้ตัวดำเนินการระดับบิตหมายความว่าก่อนอื่นจะแปลงเป็น int จากนั้นทำการดำเนินการแล้วแปลงกลับเป็นจำนวนจุดลอยตัว
โผล่

1
@poke แก้ไขพวกมันเป็นแบบ Number แต่ก็ดีที่รู้ว่ามีประสิทธิภาพในภาษาที่พิมพ์ออกมาอย่างรุนแรง
Robert Brisita

8

แล้วเรื่องต่อไปนี้ล่ะ? ฉันทดสอบสิ่งนี้ใน IE เท่านั้น แต่ก็ยินดีที่จะจัดการกับสตริงที่แสดงความยาวจำนวนจริงจำนวนที่เป็นจำนวนเต็มหรือลอยตัวและฟังก์ชั่นทั้งสองกลับเท็จเมื่อผ่านบูลีนไม่ได้กำหนดเป็นโมฆะอาร์เรย์หรือวัตถุ (ขึ้นอยู่กับคุณว่าคุณต้องการละเว้นช่องว่างนำหน้าหรือต่อท้ายเมื่อมีการส่งผ่านสตริง - ฉันคิดว่ามันจะไม่ถูกละเว้นและทำให้ทั้งสองฟังก์ชันส่งคืนค่าเท็จ)

function isEven(n) {
   return /^-?\d*[02468]$/.test(n);
}

function isOdd(n) {
   return /^-?\d*[13579]$/.test(n);
}

2
สำหรับการติดตั้งของฉัน isEven (2.122e3) จะส่งกลับค่าจริง แต่ isEven ("2.122e3") จะส่งกลับค่าเท็จ ในทางกลับกัน isEven () ของฉันล้มเหลวในจำนวนมากเนื่องจาก JS ทำให้พวกเขาอยู่ในรูปแบบเลขชี้กำลังเมื่อแปลงเป็นสตริงสำหรับการทดสอบ regex โอ้ดี
nnnnnn

@MartijnScheffer - อย่าลังเลที่จะส่งใบเรียกเก็บเงินสำหรับความทรงจำพิเศษทั้งหมดที่คุณจะต้องซื้อ โปรดทราบว่าคำถามนั้นรวมถึงการแปลงจากประเภทอื่นเป็นตัวเลขและจุดที่ชัดเจนของสิ่งที่ฉันแนะนำที่นี่คือการมีฟังก์ชั่นหนึ่งบรรทัดอย่างง่ายที่จัดการตัวเลขและสตริง แน่นอนตามความคิดเห็นของฉันนี้ไม่จริงจัดการทุกกรณีที่เป็นไปได้ แต่ก็ยังอาจมีประโยชน์ - regex เป็นวิธีที่ง่ายที่สุดในการตรวจสอบข้อมูลที่ผู้ใช้ป้อนซึ่งจะเป็นสตริงแรก
nnnnnn

ฉันโพสต์ความคิดเห็นที่นี่? ฉันไม่เห็น แต่ฉันสามารถทำได้ถ้าคุณต้องการอย่างใดอย่างหนึ่ง! นี่ไม่ใช่ทางออกที่ถูกต้องนี่คือช้าลงหลายร้อยครั้งและเรากำลังพูดถึงตัวเลขไม่สตริงถ้าคุณต้องการตรวจสอบว่าสตริงที่ถูกต้อง number และจำนวนเต็มที่สามารถจัดการ separatly ได้
Martijn Scheffer

@MartijnScheffer - ใช่มีความคิดเห็นจากคุณดูเหมือนว่าจะถูกลบในบางจุดตั้งแต่คำตอบของฉัน โปรดทราบว่าคำถามไม่ได้เกี่ยวกับตัวเลขเท่านั้นรหัสของ OP รวมถึงการแปลงจากประเภทอื่น ๆ อย่างไรก็ตามขอขอบคุณสำหรับความคิดเห็นของคุณ
nnnnnn

7

หมายเหตุ: นอกจากนี้ยังมีตัวเลขติดลบ

function isOddInteger(n)
{
   return isInteger(n) && (n % 2 !== 0);
}

ที่ไหน

function isInteger(n)
{
   return n === parseInt(n, 10);
}

1
การแยกวิเคราะห์ไม่ต้องการ radix ที่นี่หรือ
blablabla

@blablabla ใช่การใช้งานไม่ได้ทั้งหมดจะถือว่า radix = 10
Rodrigo

การอ้างอิงที่ดีของค่าลบ คำตอบของ Robert Brisita (ซึ่งเพิ่มในภายหลัง) ครอบคลุมสิ่งนี้เช่นกัน
Jacksonkr

4

ทำไมไม่ทำเช่นนี้:

    function oddOrEven(num){
        if(num % 2 == 0)
            return "even";
        return "odd";
    }
    oddOrEven(num);

หรือแม้กระทั่งfunction isEven(num) { return num % 2 == 0}
chiapa

3
หรือกับ ES6:const oddOrEven = num => num % 2 === 0 ? 'even' : 'odd'
enguerran


1
var isEven = function(number) {
    // Your code goes here!
    if (number % 2 == 0){
       return(true);
    }
    else{
       return(false);    
    }
};

2
if ( <expression> ) return true else return falseกระบวนทัศน์สามารถเสมอได้ง่ายไปreturn ( <expression> )(ตั้งแต่การแสดงออกในนั้นif แล้วก็มักจะเป็นแบบบูลหนึ่ง)
เจอราลด์ Broser

บอกว่า return ไม่ใช่ฟังก์ชันเหมือนกับว่าถ้าไม่ใช่ function มันใช้งานได้ดีในการใช้วงเล็บเมื่อคืนค่า (แม้ว่าจะไม่มีประโยชน์ที่นี่)
Martijn Scheffer

1

การแก้ไข / ปรับปรุงอย่างง่ายของคำตอบของ Steve Mayne!

function isEvenOrOdd(n){
    if(n === parseFloat(n)){
        return isNumber(n) && (n % 2 == 0);
    }
    return false;
}

หมายเหตุ: คืนเท็จถ้าไม่ถูกต้อง!


1

เราต้องการโค้ดหนึ่งบรรทัดสำหรับสิ่งนี้!

นี่เป็นวิธีที่ใหม่กว่าและเป็นทางเลือกในการทำสิ่งนี้โดยใช้ไวยากรณ์ES6ใหม่สำหรับฟังก์ชั่น JS และไวยากรณ์หนึ่งบรรทัดสำหรับการif-elseเรียกใช้คำสั่ง:

const isEven = num => ((num % 2) == 0) ? true : false;

alert(isEven(8));  //true
alert(isEven(9));  //false
alert(isEven(-8)); //true

1
let isEven = num => num % 2 === 0ซึ่งเป็นสั้นลง :-) แต่จริงๆแล้วมันไม่ต่างกับคำตอบอื่น ๆ อีกมากมายที่นี่
RobG

1

จำนวนน้อย

x % 2 == 0; // Check if even

!(x & 1); // bitmask the value with 1 then invert.

((x >> 1) << 1) == x; // divide value by 2 then multiply again and check against original value

~x&1; // flip the bits and bitmask

0

วิธีการที่แตกต่างกัน:

var isEven = function(number) {
  // Your code goes here!
  if (((number/2) - Math.floor(number/2)) === 0) {return true;} else {return false;};
};

isEven(69)


0
if (testNum == 0);
else if (testNum % 2  == 0);
else if ((testNum % 2) != 0 );

ไม่มีคำอธิบายการบริจาคของคุณมีค่ามาก นอกจากนี้ยังมีการทำซ้ำข้อมูลที่มีการนำเสนอไปแล้วในการอภิปราย
Cindy Meister

ขอบคุณซินดี้! เพียงแค่เสนอทางออก!
Lindsay

แต่ ... มันไม่ได้ทำอะไรเลย มันจะไม่ส่งคืนอะไรหรือ
nnnnnn

0

บางทีนี่อาจ? if (ourNumber% 2! == 0)


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


0

for(var a=0; a<=20;a++){
   if(a%2!==0){
       console.log("Odd number "+a);
   }
}

for(var b=0; b<=20;a++){
    if(b%2===0){
        console.log("Even number "+b);  
    }     
 }


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

-1

เพื่อทดสอบว่าคุณมีเลขคี่หรือเลขคู่หรือไม่

const comapare = x => integer(checkNumber(x));

function checkNumber (x) {
   if (x % 2 == 0) {
       return true;
   } 
   else if (x % 2 != 0) {
       return false;
    }
}

function integer (x) {
   if (x) {
       console.log('even');
   } 
   else {
       console.log('odd');
    }
}

-1

ใช้สไตล์จาวาสคริปต์ที่ทันสมัย:

const NUMBERS = "nul one two three four five six seven ocho nueve".split(" ")

const isOdd  = n=> NUMBERS[n % 10].indexOf("e")!=-1
const isEven = n=> isOdd(+n+1)

isOdd('5'))ผลตอบแทนจริง isEven('5')ผลตอบแทนจริงเช่นกัน isOdd(NaN)เกิดข้อผิดพลาด :-(
RobG

แก้ไขisEven('5')แล้ว isOdd(NaN)อาจจะผิดพลาด
gunn

1
โฮสต์สคริปต์ไม่ควรจัดการข้อผิดพลาดฟังก์ชันควร ผมก็บอกเสมอถ่ายโอนข้อมูลหลักไม่ได้เป็นการเลิกจ้างตามปกติ ;-)
RobG


-2
function isEven(n) {return parseInt(n)%2===0?true:parseInt(n)===0?true:false}

เมื่อ 0 / แม้ต้องการ แต่

isEven(0) //true
isEven(1) //false
isEven(2) //true
isEven(142856) //true
isEven(142856.142857)//true
isEven(142857.1457)//false


return parseInt(n)%2===0?true:parseInt(n)===0หรือ แต่จากนั้นอีกครั้งนี่เป็นคำตอบเดียวกับที่มีอยู่แล้วในนี้
นอกรีต Monkey

1
return parseInt(n)%2 === 0 || parseInt(n) === 0หรือ แต่ทำไมparseInt ? ที่ส่งกลับค่าจริงสำหรับค่าเช่น "32foo" และ12.5ซึ่งไม่ได้
RobG

-2
if (i % 2) {
return odd numbers
}

if (i % 2 - 1) {
return even numbers
}

1
คำเตือนของการหารจำนวนใด ๆ ด้วย 2 จะเป็น 2 เมื่อใด
user85421

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