1
votes

JavaScript - passer un opérateur booléen (ou bit à bit) comme argument?

En C #, il existe différentes manières de procéder C # Passer l'opérateur au niveau du bit comme paramètre spécifiquement l'objet "Bitwise.Operator.OR", mais est-ce que quelque chose comme ça peut être fait en JavaScript? Par exemple:

function check(num1, num2, op) {
    return num1 op num2; //just an example of what the output should be like
}

check(1,2, >); //obviously this is a syntax error, but is there some kind of other object or bitwise operator of some kind I can plug into the place of ">" and change the source function somehow?


18 commentaires

Non, il n'y a aucun moyen. Le seul moyen est de passer une chaîne contenant un opérateur et d'utiliser eval () ce qui n'est pas bon.


@MaheerAli nouvelle fonction est meilleure ici.


@Kaiido comment cela fonctionnerait-il?


@Kaiido nouvelle fonction utilise également eval ()


@MaheerAli les termes ">" et ">>" n'ont-ils pas des constructeurs comme true et false?


Ce serait répétitif, mais vous pourriez créer un objet dont les clés sont les opérateurs, dont les valeurs sont une fonction à laquelle vous passez le num1 et num2 , qui renvoie le évalué expression


@MaheerAli non ce n'est pas le cas, du moins pas la partie perverse: vous n'allez pas à la portée globale et c'est généralement mieux optimisé


@CertainPerformance à quoi ressembleraient les valeurs de cet objet s'il y avait plus de 2 variables


Cela dépendrait de l'opérateur. Le seul opérateur ternaire que je connaisse dans JS est l'opérateur conditionnel cond1? expr1: expr2


@CertainPerformance Je veux dire pour l'oject avec chaque clé étant un opérateur différent - pour couvrir tous les opérateurs. À quoi cela ressemblerait-il? var operators = {">": (num1, num2) => num1> num2, "<": (num1, num2) => num1


@CertainPerformance les opérateurs n'ont-ils pas une sorte de constructeur? Dans quoi sont-ils compilés?


Je pensais que le seul opérateur qui utilise plus de 2 expressions est l'opérateur conditionnel. Peut-être que '?:': (Cond, expr1, expr2) => cond? expr1: expr2


@CertainPerformance et si vous aviez une expression 2 <5 && 8 <10 && 9> 2 ... AKA, l'opérateur "&&", ou "||", ou "&", etc.


@CertainPerformance, ils ont parlé des opérateurs bit à bit , même s'ils ont utilisé le > dans leur exemple.


@Kaiido dont "ils"


Tous les opérateurs au niveau du bit cherchent à accepter deux ou un seul argument. Si vous avez plusieurs opérateurs, alors (en utilisant l'exemple d'objet) référence cet objet plusieurs fois, vérifiez ['&&'] (vérifiez ['<'] (2, 5), vérifiez ['<'] (8, 10)) etc, quelque chose comme ça


@CertainPerformance donc la seule façon d'écrire 2 + 3 + 4 + 5 + 6 serait d'utiliser l'imbrication?


Ce n'est pas la seule manière, mais c'est une manière


4 Réponses :


5
votes

Vous pouvez créer un objet avec des clés comme opérateurs et des valeurs comme fonctions. Vous aurez besoin de la notation Bracket pour accéder aux fonctions.

Vous pouvez utiliser les paramètres de repos et some () et every () pour plus de deux paramètres pour && ,||.

Pour l'opérateur bit à bit ou +, -, *, / plusieurs valeurs, vous pouvez utiliser réduire ()

const check = {
  '>':(n1,n2) => n1 > n2,
  '<':(n1,n2) => n1 < n2,
  '&&':(...n) => n.every(Boolean),
  '||':(...n) => n.some(Boolean),
  '&':(...n) => n.slice(1).reduce((ac,a) => ac & a,n[0])
}

console.log(check['>'](4,6)) //false
console.log(check['<'](4,6)) /true
console.log(check['&&'](2 < 5, 8 < 10, 9 > 2)) //true

console.log(check['&'](5,6,7)  === (5 & 6 & 7))


6 commentaires

et s'il y avait plus que 2 nombres


@bluejayke Comment il pourrait y avoir plus de deux nombres dans un opérateur supérieur ou inférieur à?


@bluejayke Vous ne pouvez pas avoir plus de deux opérandes pour > ou <. Si vous en voulez plus pour || et && , consultez la réponse modifiée.


OK, je suppose que c'est à peu près la réponse, pouvez-vous encore expliquer pourquoi "Boolean" a été passé à n.every? et aussi comment feriez-vous cela pour les opérateurs binaires, ou en particulier l'opérateur "&", qui continue à l'expression suivante même si c'est faux, par exemple?


@bluejayke chaque méthode prend un rappel. Alors je lui ai passé Boolean . Il vérifiera si tout (dans le premier cas) ou au moins (dans le second cas) est vrai. n.every (Boolean) est identique à n.every (x => x)


@bluejayke Je ne connais pas grand chose aux opérateurs bit à bit mais. Il pense que vous pouvez utiliser reduction () pour cela voir la réponse mise à jour



1
votes

Vous pouvez faire exactement la même chose suggérée par les réponses liées:

const Operators = {
  LOGICAL: {
    AND: (x, y) => x && y,
    OR: (x, y) => x || y,
    GT: (x, y) => x > y,
    // ... etc. ...
  },
  BITWISE: {
    AND: (x, y) => x & y,
    OR: (x, y) => x | y,
    XOR: (x, y) => x ^ y,
    // ... etc. ...
  }
};

// Use it like this
check(3, 5, Operators.BITWISE.AND);

Vous pouvez également créer un objet qui fournit toutes ces opérations:

function check(num1, num2, op) {
  return op(num1, num2);
}

// Use it like this
check(3, 7, (x, y) => x > y);


5 commentaires

et s'il y a plus de 2 variables par opérateur, comme true && false && true && false etc .....


Cela semble également être différent de la fonction C #: Bitwise.Operation (1, 2, Bitwise.Operator.OR); // 3, apparemment "Bitwise.Operator.OR" est une constante, pas une fonction


Heureusement, l'imbrication nous aide ici: BITWISE.AND (3, BITWISE.AND (7, BITWISE.AND (12, 93))) est identique à 3 & 7 & 12 & 93 :-D


stackoverflow.com/a/36107908/135978 - Dans l'exemple de ici c'est définitivement une méthode statique, pas une constante.


Bon point, alors c'est juste une question de suivi récursif à travers lui



0
votes

Ce n'est pas possible. Mais une façon d'aborder cela est de faire ce qui suit:

function evaluate(v1, v2, op) {
    let res = "" + v1 + op + v2;
    return eval(res)
}
console.log(evaluate(1, 2, "+"));
# outputs 3

Mais soyez prudent en passant des args car ils seront évalués, ce qui est dangereux si du code piraté est passé à la fonction.


1 commentaires

Eh bien, si vous utilisez eval, ne pouvez-vous pas simplement évaluer le booléen entier?



1
votes

Que diriez-vous de quelque chose comme:

 function binaryOperation( obj1, obj2, operation ) {
     return operation( obj1, obj2 );
 }
 function greaterThan( obj1, obj2 ) {
    return obj1 > obj2 ;
 }
 function lessThan( obj1, obj2 ) {
    return obj1 < obj2 ;
 }
 alert( binaryOperation( 10, 20, greaterThan ) );
 alert( binaryOperation( 10, 20, lessThan ) );


0 commentaires