2010-07-15 12 views
2

Je cherchais à voir s'il est possible de définir plusieurs variables avec un opérateur ternaire. J'ai un peu google, mais je n'ai rien trouvé. J'ai commencé à tester quelques idées et j'ai trouvé quelque chose de proche - mais aussi un comportement étrange; des idées sur ce qui se passe? Et, est-il possible de définir plus d'un var en une seule opération ternaire? Si oui, y a-t-il une bonne façon de le faire?Est-il possible de définir plusieurs variables avec un opérateur ternaire?

$i=9; 
($i==9)?($w=3|$r=2):($w=7|$r=1); 
echo 'w= '.$w.' r= '.$r;//w= 3 r= 2 


$i=9; 
($i==9)?($w=4|$r=2):($w=7|$r=1); 
echo 'w= '.$w.' r= '.$r;//w= 6 r= 2 


$i=9; 
($i==9)?($w=3|$r=7):($w=7|$r=1); 
echo 'w= '.$w.' r= '.$r;//w= 7 r= 7 


$i=444; 
($i==9)?($w=4|$r=2):($w=7|$r=1); 
echo 'w= '.$w.' r= '.$r;//w= 7 r= 1 


$i=444; 
($i==9)?($w=4|$r=2):($w=1|$r=1); 
echo 'w= '.$w.' r= '.$r;//w= 1 r= 1 

... Merci


Edit:

Je l'ai fait un peu plus de tests, et a constaté que cela fonctionne correctement:

($i==9)?($w=4 AND $r=7):($w=7 AND $r=1); 

cependant, je suis Je ne sais pas si c'est correct. Et je suis curieux de savoir ce qui se passe dans le premier exemple.

Répondre

7

Comme Chadwick a expliqué, en utilisant les AND ou OR opérateurs logiques ne fonctionnera pas la façon dont vous voulez qu'ils:

$i = 0; $w = 0; $r = 0; 
($i==9) ? ($w=4 AND $r=7) : ($w=7 AND $r=1); 
echo "w = $w, r = $r\n"; 
// w = 7, r = 1 

$i = 0; $w = 0; $r = 0; 
($i==9) ? ($w=0 AND $r=7) : ($w=0 AND $r=1); 
echo "w = $w, r = $r\n"; 
// w = 0, r = 0 

Cependant, si vous voulez vraiment faire de multiples tâches dans une instruction, vous pouvez utiliser la construction list:

$i = 0; $w = 0; $r = 0; 
($i==9) ? 
    (list($w, $r) = array(4, 7)) : 
    (list($w, $r) = array(7, 1)); 
echo "w = $w, r = $r\n"; 
// w = 7, r = 1 

$i = 0; $w = 0; $r = 0; 
($i==9) ? 
    (list($w, $r) = array(0, 7)) : 
    (list($w, $r) = array(0, 1)); 
echo "w = $w, r = $r\n"; 
// w = 0, r = 1 
3

L'opérateur OR raccourcit les secondes affectations que vous effectuez dans les expressions de votre ternaire. Donc, la seconde assignation n'est pas faite si la première est non nulle.

Si vous passez à un AND statment (ou &&) la seconde affectation dans l'expression dépend toujours de la première: si les premiers Equivaut à 0 (à savoir faux), puis la seconde moitié du ET ne sont pas évalués. C'est probablement plus difficile à déboguer que le premier, car il est probablement rare que la première valeur soit zéro. Il peut ne jamais être, et cela fonctionnera toujours ... jusqu'à ce qu'un jour ...

L'opérateur ternaire est juste raccourci pour if...else... avec des expressions simples plutôt que des instructions multiples. Si vous voulez plusieurs, attributions indépendantes je recommande fortement d'aller avec standard si ... sinon ... Plus facile à lire tout autour.

0

Il vous manque une barre verticale pour former une clause OR:

($i==9)?($w=3|$r=2):($w=7|$r=1); 

Il devrait être:

($i == 9) ? ($w = 3 || $r = 2) : ($w = 7 || $r = 1); 

Et oui comme on peut le voir vous avez plus d'une variable $w et $r utilisé Là.

3

Je vais essayer d'expliquer pourquoi votre code actuel se comporte comme il se comporte. Première chose à savoir: | est l'opérateur bitwise-or. Deuxième chose à savoir: | a une plus grande précession de l'opérateur que = et est donc exécuté en premier.Voyons donc le premier code: $w=3|$r=2. Selon la priorité de l'opérateur, ce code peut être écrit de cette façon: $w=(3|$r=2). Donc, $r est réglé correctement, puis $w=3|2 est effectuée. 3 dans le système double est 11 et 2 est 10.

11 
| 10 
==== 
    11 

Le résultat est donc correct.

Maintenant, regardons le second code:

$w=4|$r=2 est le même que $w=(4|$r=2). $r est définie correctement, puis $w=4|2 est effectuée. 4 est 100 dans le système dual, 2 est 010:

100 
| 010 
===== 
    110 

Et 110 dans le système décimal est 6!

Donc, maintenant vous savez qu'il ya les mauvaises valeurs viennent, maintenant nous allons trouver une solution:

L'utilisation && ici est découragé, parce que si la première valeur a été fixée à 0 le second ne serait pas fixé à tous . De plus, il a une mauvaise priorité d'opérateur: $w=1&&$r=2 est identique à $w=(1&&$r=2). Donc $w sera toujours affecté soit true ou false.

Une solution possible consisterait à utiliser l'opérateur xor. Cet opérateur exige que les deux parties à exécuter et il a le precendance parfait:

$i == 9 ? ($w = 1 xor $r = 2) : ($w = 2 xor $r = 3); 

Mais, vous pouvez l'imaginer, cela est difficile à lire, donc mieux ne pas l'utiliser ...

+0

+1 merci pour la excellente explication. J'ai lu que le single pipe était un opérateur bitwise, mais je ne savais pas ce qu'il faisait. Des trucs intéressants. Merci encore! – stormdrain

+0

+1 pour une bonne explication du problème. – Mike