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


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.