값 목록과 비교하여 변수 평등 확인


133

변수를 확인하고 있습니다. foo 의 개수가 같은지 있습니다. 예를 들어

if( foo == 1 || foo == 3 || foo == 12 ) {
    // ...
}

요점은 그러한 사소한 작업을위한 코드가 다소 많다는 것입니다. 나는 다음을 생각해 냈다.

if( foo in {1: 1, 3: 1, 12: 1} ) {
    // ...
}

그러나 객체의 항목에 중복 값을 제공해야하기 때문에 이것은 나에게 완전히 호소력이 없습니다.

누구나 여러 값에 대해 평등 검사를 수행하는 적절한 방법을 알고 있습니까?


왜 이런 비교 를하는지 아는 것이 중요하기 때문에 이와 같은 것을 결정할 때 더 큰 맥락이 필요하다고 생각합니다 .
— Pointy

글쎄, 내가 만들고있는 게임에서 어떤 함수를 호출 해야하는지 결정하기 위해 키보드 코드를 확인하고 있습니다. 브라우저마다 키마다 키 코드가 다르기 때문에 여러 값과 비교해야합니다.
— pimvdb

여러 가지 방법에 대한 성능 테스트 확인, 논리 연산자로 runkit.com/pramendra/58cad911146c1c00147f8d8d
— Pramendra Gupta

답변:


175

배열을 사용할 수 있습니다 indexOf:

if ([1,3,12].indexOf(foo) > -1)

1
난이게 좋아. > -1을 사용하지 않기 위해 필자가 생각한 프로토 타입을 통해 '포함'기능을 만들 수도 있습니다.
— pimvdb

1
@pimvdb : indexOfECMAScript 5th Edition 이후에만 사용 가능한 자체 구현이 필요할 수 있습니다 .
— Gumbo

또 다른 대답으로 이것은 실제로 언급되어 있지만, 나는 그것을 몰랐습니다.
— pimvdb

'>'가 어떻게 든 '! =='보다 낫습니까?
— Max Waterman

117

ECMA2016에서는 포함 방법을 사용할 수 있습니다 . 내가 본 가장 깨끗한 방법입니다. (IE를 제외한 모든 주요 브라우저에서 지원 (폴리 필은 링크에 있습니다)

if([1,3,12].includes(foo)) {
    // ...
}

4
변수 if([a,b,c].includes(foo))또는 문자열의 경우if(['a','b','c'].includes(foo))
— Hastig Zusammenstellen

if([a,b,c].includes(foo))인용 부호가 문자열로 만들기 때문에 변수 => @HastigZusammenstellen
— iambinodstha

2
@BinodShrestha 나는 뭔가 빠진 것이 아니라면 내가 쓴 것이라고 생각합니다. "변수 .. 또는 문자열 ..."
— Hastig Zusammenstellen

16

제공된 답변을 사용하여 다음과 같이 끝났습니다.

Object.prototype.in = function() {
    for(var i=0; i<arguments.length; i++)
       if(arguments[i] == this) return true;
    return false;
}

다음과 같이 호출 할 수 있습니다.

if(foo.in(1, 3, 12)) {
    // ...
}

편집 : 최근 에이 '트릭'을 보았습니다. 값이 문자열이고 특수 문자가 포함되어 있지 않은 경우 유용합니다. 특수 문자의 경우 이스케이프로 인해 추악 해지고 그로 인해 오류가 발생하기 쉽습니다.

/foo|bar|something/.test(str);

더 정확하게 말하면 정확한 문자열을 확인하지만 간단한 동등성 테스트에서는 더 복잡합니다.

/^(foo|bar|something)$/.test(str);

5
선량! inJavascript의 키워드 인 작동합니다 . 예를 들어, function in() {}; in()Firefox에서 실행 하면 구문 오류가 발생하며 왜 코드가 그렇지 않은지 잘 모르겠습니다. :-)
— Ben Blank

3
또한 불행한 방식으로 Object.prototype영향을 미치기 때문에 확장하는 것은 나쁜 습관으로 간주되는 경우가 많습니다 for (foo in bar). 아마도 그것을 function contains(obj) { for (var i = 1; i < arguments.length; i++) if (arguments[i] === obj) return true; return false; }객체로 바꾸고 인수로 전달합니까?
— Ben Blank

귀하의 반응에 감사드립니다.이 코드 자체가 아름답게 작동하는 동안 Google Closure Compiler는 컴파일하는 동안 오류를 반환합니다. 어쨌든 도우미 클래스 Object.prototype는 언급 한 것처럼 확장 하는 것 보다이 작업을 더 잘 수행 할 수 있다고 제안되었습니다 . 그러나 확인을위한 표기법이 foo.in(1, 2, "test", Infinity)파이처럼 사랑스럽고 간단하기 때문에이 방법을 선호합니다 .
— pimvdb

그리고 in()Chrome 에서 함수를 정의하는 일반적인 방법은 실패하지만 프로토 타입은 작동합니다 ... :)
— pimvdb

3
Object.prototype을 확장하는 것은 안티 패턴이며 사용해서는 안됩니다. 대신 함수를 사용하십시오.
— 버논

9

당신은 쓸 수 있습니다 if(foo in L(10,20,30))당신이 정의하는 경우 L로

var L = function()
{
    var obj = {};
    for(var i=0; i<arguments.length; i++)
        obj[arguments[i]] = null;

    return obj;
};

이전 답변보다 훨씬 명확합니다. 감사합니다!
— pimvdb

2
프로토 타입 함수도 배열 / 객체에 '있어'라고 언급하는 것이 현명하다고 생각합니다. 따라서 배열 / 객체의 프로토 타입에 '제거'기능이 있으면 코딩 'remove' in L(1, 3, 12)하지 않으면 항상 true를 반환합니다. '제거'를 지정하여 목록에 넣으십시오.
— pimvdb

7

이것은 쉽게 확장 가능하고 읽을 수 있습니다.

switch (foo) {
    case 1:
    case 3:
    case 12:
        // ...
        break

    case 4:
    case 5:
    case 6:
        // something else
        break
}

그러나 반드시 쉬운 것은 아닙니다 :)


각 값 옆에 주석을 추가하여 값과 관련된 내용을 설명하고 싶을 때 실제로이 방법을 사용했습니다.이 방법은 가장 읽기 쉬운 방법이었습니다.
— pholcroft

각 값과 관련된 내용을 설명해야하는 경우 @pholcroft 열거 형 또는 클래스를 만들고 속성을 설명적인 이름으로 작성해야합니다.
— red_dorian

6
var a = [1,2,3];

if ( a.indexOf( 1 ) !== -1 ) { }

indexOf는 핵심 ECMAScript에 없습니다. IE 및 가능하면 Array.prototype.indexOf를 지원하지 않는 다른 브라우저에 대한 스 니펫이 필요합니다.

if (!Array.prototype.indexOf)
{
  Array.prototype.indexOf = function(searchElement /*, fromIndex */)
  {
    "use strict";

    if (this === void 0 || this === null)
      throw new TypeError();

    var t = Object(this);
    var len = t.length >>> 0;
    if (len === 0)
      return -1;

    var n = 0;
    if (arguments.length > 0)
    {
      n = Number(arguments[1]);
      if (n !== n)
        n = 0;
      else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0))
        n = (n > 0 || -1) * Math.floor(Math.abs(n));
    }

    if (n >= len)
      return -1;

    var k = n >= 0
          ? n
          : Math.max(len - Math.abs(n), 0);

    for (; k < len; k++)
    {
      if (k in t && t[k] === searchElement)
        return k;
    }
    return -1;
  };
}

모질라의 사본이다. 연결하기에는 너무 게으르다. developer.mozilla.org/en/JavaScript/Reference/Global_Objects/…
— meder omuraliev

실제로 비트를 시프트하지 않는 경우 len을 정의 할 때 비트 시프트에 대한 이유가 있습니까? 여기에는 암묵적인 강제가 있습니까?
— jaredad7

3

또한 결과를 확인하는 값이 모두 고유하기 때문에 Set.prototype.has () 도 사용할 수 있습니다 .

var valid = [1, 3, 12];
var goodFoo = 3;
var badFoo = 55;

// Test
console.log( new Set(valid).has(goodFoo) );
console.log( new Set(valid).has(badFoo) );


2

이제이 시나리오를 해결하는 더 나은 솔루션이 있지만 다른 방법으로 선호합니다.

const arr = [1,3,12]
if( arr.includes(foo)) { // it will return true if you `foo` is one of array values else false
  // code here    
}

인덱스를 확인 해야하는 indexOf 검사보다 위의 솔루션을 선호했습니다.

문서 포함

if ( arr.indexOf( foo ) !== -1 ) { }

1

나는 받아 들인 대답을 좋아했지만 배열을 취할 수있는 것이 좋을 것이라고 생각했기 때문에 이것을 다음과 같이 확장했습니다.

Object.prototype.isin = function() {
    for(var i = arguments.length; i--;) {
        var a = arguments[i];
        if(a.constructor === Array) {
            for(var j = a.length; j--;)
                if(a[j] == this) return true;
        }
        else if(a == this) return true;
    }
    return false;
}

var lucky = 7,
    more = [7, 11, 42];
lucky.isin(2, 3, 5, 8, more) //true

로 변경 ==하여 유형 강제 변환을 제거 할 수 있습니다 ===.


1

Underscore에 액세스 할 수 있으면 다음을 사용할 수 있습니다.

if (_.contains([1, 3, 12], foo)) {
  // ...
}

contains Lodash에서도 사용되었지만 (V4 이전) 이제는 includes

if (_.includes([1, 3, 12], foo)) {
  handleYellowFruit();
}

1

이것은 작은 도우미 arror 기능입니다.

const letters = ['A', 'B', 'C', 'D'];

function checkInList(arr, val) {
  return arr.some(arrVal => val === arrVal);
}

checkInList(letters, 'E');   // false
checkInList(letters, 'A');   // true

더 많은 정보는 여기에 ...


아주 좋은 접근법 : 당신의 아이디어에서 시작하여 당신은 또한 도우미 기능 없이도 할 수 있습니다 :const valToCheck = 'E'; const check = ['A', 'B', 'C', 'D'].some(option => option === valToCheck); // false
— Giorgio Tempesta

그러나 일단 코드를 조정하기 시작하면 includes@alister의 답변에서와 같이 더 나은 옵션이됩니다.const valToCheck = 'E'; const check = ['A', 'B', 'C', 'D'].includes(valToCheck); // false
— Giorgio Tempesta

0

jQuery inArray 함수와 값 배열을 사용하여이를 수행했습니다.

myArr = ["A", "B", "C", "C-"];

var test = $.inArray("C", myArr)  
// returns index of 2 returns -1 if not in array

if(test >= 0) // true

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.