programing tip

여러 값과 일치하는 if 문

itbloger 2020. 10. 31. 09:25
반응형

여러 값과 일치하는 if 문


이 if 문을 작성하는 더 쉬운 방법은 무엇입니까?

if (value==1 || value==2)

예를 들어 ... SQL에서는 where value in (1,2)대신 where value=1 or value=2.

나는 모든 기본 유형 ... 문자열, 정수 등으로 작동하는 것을 찾고 있습니다.


어때 :

if (new[] {1, 2}.Contains(value))

그래도 해킹입니다 :)

또는 자신 만의 확장 메서드를 만들어도 괜찮다면 다음을 만들 수 있습니다.

public static bool In<T>(this T obj, params T[] args)
{
    return args.Contains(obj);
}

다음과 같이 사용할 수 있습니다.

if (1.In(1, 2))

:)


SQL의 'IN'을 에뮬레이트하는 더 복잡한 방법 :) :

public static class Ext {    
    public static bool In<T>(this T t,params T[] values){
        foreach (T value in values) {
            if (t.Equals(value)) {
                return true;
            }
        }
        return false;
    }
}

if (value.In(1,2)) {
    // ...
}

그러나 표준 방식으로 이동하면 더 읽기 쉽습니다.

편집 : @Kobi의 제안에 따라 더 나은 솔루션 :

public static class Ext {    
    public static bool In<T>(this T t,params T[] values){
        return values.Contains(t);
    }
}

이것이 당신이 찾고있는 것입니까?

if (new int[] { 1, 2, 3, 4, 5 }.Contains(value))

목록이 있으면 .Contains (yourObject)를 사용할 수 있습니다. 기존 항목 (예 : where)을 찾고 있다면 사용할 수 있습니다. 그렇지 않으면 Linq .Any () 확장 메서드를 살펴보십시오.


또는 앞으로 1 또는 2 이외의 값을 테스트하는 것이 switch 문을 사용하는 경우 더 많은 유연성을 제공합니다.

switch(value)
{
case 1:
case 2:
   return true;
default:
   return false
}

Linq를 사용하여

if(new int[] {1, 2}.Contains(value))

하지만 원본이 더 빠르다고 생각해야합니다.


긴 목록에서 고정 된 값 목록의 값을 여러 번 검색하는 경우 HashSet <T>를 사용해야합니다. 목록이 매우 짧으면 (<~ 20 개 항목)이 테스트 HashSet 대 목록 성능을 기반으로 목록의 성능 이 향상 될 수 있습니다.

HashSet<int> nums = new HashSet<int> { 1, 2, 3, 4, 5 };
// ....
if (nums.Contains(value))

일반적으로 아닙니다.

예, 목록이 Array또는 인 List경우가 있지만 일반적인 경우는 아닙니다.


이와 같은 확장 방법은 그것을 할 것입니다 ...

public static bool In<T>(this T item, params T[] items)
{
    return items.Contains(item);
}

다음과 같이 사용하십시오.

Console.WriteLine(1.In(1,2,3));
Console.WriteLine("a".In("a", "b"));

Easier is subjective, but maybe the switch statement would be easier? You don't have to repeat the variable, so more values can fit on the line, and a line with many comparisons is more legible than the counterpart using the if statement.


In vb.net or C# I would expect that the fastest general approach to compare a variable against any reasonable number of separately-named objects (as opposed to e.g. all the things in a collection) will be to simply compare each object against the comparand much as you have done. It is certainly possible to create an instance of a collection and see if it contains the object, and doing so may be more expressive than comparing the object against all items individually, but unless one uses a construct which the compiler can explicitly recognize, such code will almost certainly be much slower than simply doing the individual comparisons. I wouldn't worry about speed if the code will by its nature run at most a few hundred times per second, but I'd be wary of the code being repurposed to something that's run much more often than originally intended.

An alternative approach, if a variable is something like an enumeration type, is to choose power-of-two enumeration values to permit the use of bitmasks. If the enumeration type has 32 or fewer valid values (e.g. starting Harry=1, Ron=2, Hermione=4, Ginny=8, Neville=16) one could store them in an integer and check for multiple bits at once in a single operation ((if ((thisOne & (Harry | Ron | Neville | Beatrix)) != 0) /* Do something */. This will allow for fast code, but is limited to enumerations with a small number of values.

A somewhat more powerful approach, but one which must be used with care, is to use some bits of the value to indicate attributes of something, while other bits identify the item. For example, bit 30 could indicate that a character is male, bit 29 could indicate friend-of-Harry, etc. while the lower bits distinguish between characters. This approach would allow for adding characters who may or may not be friend-of-Harry, without requiring the code that checks for friend-of-Harry to change. One caveat with doing this is that one must distinguish between enumeration constants that are used to SET an enumeration value, and those used to TEST it. For example, to set a variable to indicate Harry, one might want to set it to 0x60000001, but to see if a variable IS Harry, one should bit-test it with 0x00000001.

One more approach, which may be useful if the total number of possible values is moderate (e.g. 16-16,000 or so) is to have an array of flags associated with each value. One could then code something like "if (((characterAttributes[theCharacter] & chracterAttribute.Male) != 0)". This approach will work best when the number of characters is fairly small. If array is too large, cache misses may slow down the code to the point that testing against a small number of characters individually would be faster.


Using Extension Methods:

public static class ObjectExtension
{
    public static bool In(this object obj, params object[] objects)
    {
        if (objects == null || obj == null)
            return false;
        object found = objects.FirstOrDefault(o => o.GetType().Equals(obj.GetType()) && o.Equals(obj));
        return (found != null);
    }
}

Now you can do this:

string role= "Admin";
if (role.In("Admin", "Director"))
{ 
    ...
} 

public static bool EqualsAny<T>(IEquatable<T> value, params T[] possibleMatches) {
    foreach (T t in possibleMatches) {
        if (value.Equals(t))
            return true;
    }
    return false;
}
public static bool EqualsAny<T>(IEquatable<T> value, IEnumerable<T> possibleMatches) {
    foreach (T t in possibleMatches) {
        if (value.Equals(t))
            return true;
    }
    return false;
}

I had the same problem but solved it with a switch statement switch(a value you are switching on) { case 1: the code you want to happen; case 2: the code you want to happen; default: return a value }

참고URL : https://stackoverflow.com/questions/3907299/if-statements-matching-multiple-values

반응형