2017-01-30 4 views
0

Je trouve souvent javscript raccourcis utiles, comme le remplacement if/else commeExiste-t-il un équivalent "while" pouvant être utilisé dans une instruction entre parenthèses en JavaScript?

if (a !== 0) { 
    b = c; 
} else { 
    b = d; 
} 

avec

b = a ? c : d; 

ou remplacement pour/boucles suivantes comme

for (let i = 0; i < array.length; i++) { 
    element = array[i]; 
    /* do something with element... */ 
} 

avec

array.forEach(element => { /* do something with element... */ }); 

J'aime particulièrement que ces et d'autres raccourcis similaires peuvent être combinés et utilisés à l'intérieur des déclarations incidentes, telles que

array.forEach(e => (x += e ? a : b, e * x)); 

(travaux)

Cependant, je n'ai pas été en mesure de trouver un raccourci ou fonctionnel équivalent à l'instruction "while" qui fonctionne entre parenthèses. Existe-t-il une telle chose?

J'ai essayé d'utiliser une instruction normale tandis qu'à l'intérieur des parenthèses, mais je m'y suis une erreur

array.forEach(e => (while (e.length > 160) { e.replace(' ', ''); }, e)); 

(ne fonctionne pas)

Je sais ce qui précède peut être réécrite sous une forme plus, comme si

array.forEach(e => { 
    while (e.length > 160) { 
    e.replace(' ', ''); 
    } 
    return e; 
}); 

(travaux)

Mais il y a des moments que je préfère vraiment un raccourci en ligne équivalent à while, plutôt que la version longue. Y-a-t-il un moyen de faire ça?

+1

Votre exemple "Forme plus longue" a exactement la même longueur que l'exemple "plus court", à l'exception de la mise en forme des espaces blancs. La seule différence est d'utiliser correctement des accolades au lieu de parens. –

+2

Votre boucle while peut ne jamais se terminer. Si vous transmettez une chaîne composée de plus de 161 caractères non-espace, vous ne quitterez jamais la boucle while. Je ne suis pas sûr de savoir pourquoi vous le faites en boucle, de toute façon; remplacer va obtenir toutes les instances du personnage en un seul appel. En outre, il semble que vous ayez une erreur de syntaxe dans votre version mono-ligne. –

+1

@SteveH. Je pense que le point est qu'il veut utiliser l'opérateur de virgule au lieu d'une déclaration de retour – Paulpro

Répondre

4

Vous pouvez utiliser la récursivité:

const cutSpace = str => str.length > 160 
    ? cutSpace(str.replace(' ', '')) 
    : str 

const trimmedStrings = array.map(cutSpace) 
+0

BTW Quelqu'un peut-il clarifier si mon exemple est un bon candidat pour l'optimisation de l'appel de queue appropriée ou devrais-je annuler le prédicat et appeler 'cutSpace' dans" else expression "? –

+2

C'est un appel de queue quelle que soit la branche dans laquelle vous l'avez placé. – Bergi

+0

@Bergi merci :) –

-2

Si vous faites une seule commande dans la boucle, vous pouvez utiliser une boucle;

array.forEach(e => for(; e.length > 160; e.replace(' ', ''));return e;}) 
+0

Alors, pourquoi cela a-t-il été rejeté? On dirait qu'il répond à la question, et semble être la version la plus compacte jusqu'à présent. – DSchnellDavis

+0

Peu importe - je l'ai compris. C'est une idée potentiellement intelligente, mais ça ne marche pas. Lorsque j'ai essayé d'utiliser ceci dans une déclaration entre parenthèses, j'ai eu une erreur, un peu comme pour l'instruction while. – DSchnellDavis

0

Il existe quelques fonctions de ce type. Pour l'exemple que vous avez donné, il ressemble à peu près à ce que vous essayez d'imiter le map function de Array, qui vous permet de produire un tableau à partir d'éléments transformés.

Exemple:

var noSpaces = array.map(str => { return str.replace(' ',''); }). 

Ceci renvoie une nouvelle matrice de chaque chaîne de caractères avec les espaces retirées (en général, une note qui fonctionne modifier l'appelant par rapport à la production d'une nouvelle version transformée La fonction .replace(). crée une nouvelle chaîne .).

Le Array prototype possède plusieurs fonctions de raccourci pour les parcourir, et peut être utilisé pour enchaîner facilement des transformations complexes et des dérivations. Map + Reduce est une combinaison assez fréquemment utilisée.

Je ne connais pas d'autres types de "sucre syntaxique" pour les boucles while en plus des raccourcis d'itération (bien, techniquement, une boucle for est une).

0

Cela pourrait ne pas être plus courte, mais il est fonctionnel:

const array = [ 
 
    '  ', 
 
    '  ', 
 
    '  ', 
 
    ' ', 
 
    ' ', 
 
    ' ', 
 
    ' ', 
 
    '', 
 
]; 
 

 
const result = array.map(e => (f => (g => x => f(g(g))(x))(h => x => f(h(h))(x)))(f => e => e.length > 2 && f(e.replace(' ', '')) || e)(e)); 
 

 
console.log(result);

j'ai changé 160-2 et utilisé map au lieu de forEach pour le rendre plus facile à démontrer.

+0

Affecter à 'e' n'est pas vraiment fonctionnel non plus, n'est-ce pas? – Bergi

+0

@Bergi Bien sûr, supprimer cette affectation raccourcit le code. J'utilisais juste cela pour démontrer que la version plus longue de l'OP ne fait rien car il n'y a pas d'assignation. – Paulpro

2

J'aime surtout que ces et d'autres raccourcis similaires peuvent être combinés et utilisés à l'intérieur des déclarations incidentes, telles que

array.forEach(e => (x += e ? a : b, e * x)); 

(travaux)

Quoi? En quelle capacité ce code "fonctionne"? Si je voyais ce code en revue, je le rejetterais immédiatement.

  • Mutation d'un état externe dans un prédicat?
  • À l'intérieur d'une boucle, néanmoins? Pour ne pas mentionner ni a ni b est utilisé.
  • Sans parler des parenthèses et de fin e * x expression est complètement jeté, aussi ... (?)

Il est si mauvais que ça fait mal.

J'ai essayé d'utiliser une instruction normale tandis qu'à l'intérieur des parenthèses, mais je m'y suis une erreur

array.forEach(e => (while (e.length > 160) { e.replace(' ', ''); }, e)); 

(ne fonctionne pas)

Eh bien, il est une erreur de syntaxe. Vous avez essayé d'utiliser une instruction où seules les expressions sont autorisées. Des choses comme if, for, while, do sont instructions. Vous ne pouvez pas mettre une instruction dans une expression (...). Même si vous pouvez utiliser une expression while ici, le code ne serait toujours quoi que ce soit. Chaque calcul est complètement mis au rebut

Je sais ce qui précède peut être réécrite sous une forme plus longue, comme tant

array.forEach(e => { 
    while (e.length > 160) { 
    e.replace(' ', ''); 
    } 
    return e; 
}); 

(travaux)

"fonctionne"? Comment cela marche-t-il? Syntaxiquement, c'est OK, mais ce n'est pas vraiment quoi que ce soit.

  • Les chaînes sont immuables si String.prototype.replace ne sera pas muter e comme je pense que vous l'imagerie qu'il fait.
  • Array.prototype.forEach ne tient pas compte de la valeur de retour dans votre fonction iterator
  • Array.prototype.forEach n'a pas de valeur de retour de son propre

Je ne peux que supposer que vous voulez dire faire quelque chose comme ça

let input = [ 
 
    'a b c d e f g h', 
 
    'i j k l m n o', 
 
    'p q r s t u', 
 
    'v w x y z' 
 
] 
 

 
input.forEach(e => { 
 
    while (e.length > 9) 
 
    e = e.replace(' ', '') 
 
    console.log(e) 
 
}) 
 

 
// abcdefg h 
 
// ijklm n o 
 
// pqr s t u 
 
// v w x y z

Voyez-vous la différence? J'utilise e = e.replace(...) car replace ne mute pas la chaîne d'entrée en place. En outre, mon itérateur est en train de faire quelque chose avec la valeur - console.log, idiot comme il pourrait être

Il semble que vous pourriez ne pas être au courant de Array.prototype.map. Comme replace, map ne mutera pas l'entrée d'origine - à la place, une nouvelle valeur est retournée. Cette fois-ci nous attribuons la valeur de retour de la carte à une nouvelle variable, output et connectez-vous que lorsque nous aurons terminé

let input = [ 
 
    'a b c d e f g h', 
 
    'i j k l m n o', 
 
    'p q r s t u', 
 
    'v w x y z' 
 
] 
 

 
let output = input.map(e => { 
 
    while (e.length > 9) 
 
    e = e.replace(' ', '') 
 
    return e 
 
}) 
 

 
console.log(output) 
 
// [ 
 
// "abcdefg h", 
 
// "ijklm n o", 
 
// "pqr s t u", 
 
// "v w x y z" 
 
// ]

Aucune de ces deux derniers extraits de code sont mauvais . Le premier a un effet secondaire d'E/S (console.log dans le forEach) mais le second est entièrement pur et entièrement fonctionnel. Il n'y a rien de mal à local mutation et il n'y a rien de mal à utiliser while dans vos programmes, d'autant plus qu'aucune machine JavaScript ne prend en charge l'optimisation des appels - la récursivité n'est pas le problème des abeilles au pays de JS.

+2

Donc, je ne donne pas vraiment la réponse à votre question, à la place cette réponse explique votre aboiement fondamentalement dans le mauvais arbre. Il est évident que votre objectif principal est de garder votre code "court", de toute façon - ce qui est une blague en considérant la structure correcte est beaucoup plus important que la soupe de syntaxe intelligente qui apparaît dans les extraits de code dans votre question. Il n'y a rien de fondamentalement mauvais avec 'for' ou' while' et vous pouvez maintenir des interfaces fonctionnelles dans votre programme même si certaines fonctions peuvent localement utiliser de telles instructions. TL: DR; n'essayez pas de contourner ces choses, surtout * par souci de brièveté. – naomik

+1

Merci d'avoir mis mes pensées en texte écrit :-) – Bergi