2017-12-07 3 views
3

Ich möchte prüfen, ob ein Wert einer Gruppe von Flags (aus einer Enumeration oder einem Objekt) entspricht.verifizieren (bitweise) wenn ein Wert mit mehreren spezifischen Flags einer Enum übereinstimmt

Gerade jetzt, ich habe mit der folgenden Funktion in Javascript (3 lobt das Snippet): kommen

function hasFlags(flags, value) { 
 
    let s = flags.reduce((sum, v) => sum += v, 0); 
 
    
 
    return (s & value) === s 
 
} 
 

 
FLAGS = { 
 
    STEP_0: 1 << 0, 
 
    STEP_1: 1 << 1, 
 
    STEP_2: 1 << 2, 
 
    STEP_3: 1 << 3, 
 
    STEP_4: 1 << 4, 
 
    STEP_5: 1 << 5, 
 
    STEP_6: 1 << 6, 
 
    STEP_7: 1 << 7 
 
} 
 

 
const needed = [ 
 
    FLAGS.STEP_2, 
 
    FLAGS.STEP_3, 
 
    FLAGS.STEP_6, 
 
] 
 

 
console.log(hasFlags(needed, 4));     // false 
 
console.log(hasFlags(needed, 8));     // false 
 
console.log(hasFlags(needed, 64));     // false 
 
console.log(hasFlags(needed, 4 + 8));    // false 
 
console.log(hasFlags(needed, 4 + 64));    // false 
 
console.log(hasFlags(needed, 8 + 64));    // false 
 
console.log(hasFlags(needed, 4 + 8 + 64));   // true 
 
console.log(hasFlags(needed, 4 + 8 + 64 + 1));  // true 
 
console.log(hasFlags(needed, 4 + 8 + 64 + 2));  // true 
 
console.log(hasFlags(needed, 4 + 8 + 64 + 1 + 2)); // true 
 
// etc...

In Python die Funktion würde wie folgt aussehen:

def hasFlags(flags, value): 
    s = sum(flags) 
    return (s & value) == s 

print hasFlags((4,8,64), 4) # False 
print hasFlags((4,8,64), 4+8+64) # True 
# ... 

Gibt es einen besseren Weg (das heißt, idiomatischer ... oder mehr Python), um die gleiche Verifikation zu machen?

Bearbeiten: Lösungen in Python und Javascript sind willkommen, aber ich bin besonders auf der Suche nach einem Algorithmus (unabhängig von der Sprache), wie ich viel im Internet gesucht und nie gefunden habe, während es mir scheint Es ist ein häufiges Problem.

+0

Was meinst du mit mehr Python? das scheint mir ok zu sein. Vielleicht bin ich falsch. – scharette

Antwort

0

Sie könnten mit Array#every überprüfen, die Ausfahrt, wenn eine Bedingung falsch ist.

const 
 
    hasFlags = (flags, value) => flags.every(flag => flag & value), 
 
    FLAGS = { 
 
     STEP_0: 1 << 0, 
 
     STEP_1: 1 << 1, 
 
     STEP_2: 1 << 2, 
 
     STEP_3: 1 << 3, 
 
     STEP_4: 1 << 4, 
 
     STEP_5: 1 << 5, 
 
     STEP_6: 1 << 6, 
 
     STEP_7: 1 << 7 
 
    }, 
 
    needed = [ 
 
     FLAGS.STEP_2, 
 
     FLAGS.STEP_3, 
 
     FLAGS.STEP_6, 
 
    ]; 
 

 
console.log(hasFlags(needed, 4));     // false 
 
console.log(hasFlags(needed, 8));     // false 
 
console.log(hasFlags(needed, 64));     // false 
 
console.log(hasFlags(needed, 4 + 8));    // false 
 
console.log(hasFlags(needed, 4 + 64));    // false 
 
console.log(hasFlags(needed, 8 + 64));    // false 
 
console.log(hasFlags(needed, 4 + 8 + 64));   // true 
 
console.log(hasFlags(needed, 4 + 8 + 64 + 1));  // true 
 
console.log(hasFlags(needed, 4 + 8 + 64 + 2));  // true 
 
console.log(hasFlags(needed, 4 + 8 + 64 + 1 + 2)); // true
.as-console-wrapper { max-height: 100% !important; top: 0; }

+0

Ich denke, die Frage fragt nach Python, nicht nach JS. –

+0

@pycoder, es sieht aus wie eine Antwort in JS ist gültig. –

0

Eine Option in Python ist ein set von Flaggen, Fahnen, wo Elemente (zum Beispiel) sind eine Aufzählung von dem enum Modul. Dies hat auch den Vorteil, dass der Subset-Operator bereits definiert ist, so dass Sie einfach needed <= flags tun können.

Ihr endgültiger Code würde wie folgt aussehen:

from enum import Enum 

class Flags(enum.Enum): 
    flag0 = {0} 
    flag1 = {1} 
    flag2 = {2} 
    ... 

def has_flags(needed, flags): 
    return needed <= flags 

needed = Flags.flag2 | 
     Flags.flag3 | 
     Flags.flag6 

print(has_flags(needed, Flags.flag2)) #false 
print(has_flags(needed, Flags.flag3)) #false 
... 
0

Wenn Kombinationen von Flags werden als Bit-Masken dargestellt Sie Mutationen und Tests mit allen Flaggen auf einmal tun können, direkt, bitweise Operatoren .

STEP_0 = 1 << 0 
STEP_1 = 1 << 1 
STEP_2 = 1 << 2 
STEP_3 = 1 << 3 
STEP_4 = 1 << 4 
STEP_5 = 1 << 5 
STEP_6 = 1 << 6 
STEP_7 = 1 << 7 

def has_flags(flags_to_check_for, cur_flags): 
    return (cur_flags & flags_to_check_for) == flags_to_check_for 

desired_flags = STEP_2 | STEP_3 | STEP_6 

cur_flags = STEP_2 
print has_flags(desired_flags, cur_flags) # False 
cur_flags |= STEP_3 
cur_flags |= STEP_6 
print has_flags(desired_flags, cur_flags) # True 
# ... 
Verwandte Themen