2017-01-30 8 views
0

Я часто JavScript ярлыки полезны, например, замена если/другое заявления какЕсть ли эквивалент «while», который можно использовать в скобках в JavaScript?

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

с

b = a ? c : d; 

или замена для/следующих петель, как

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

с

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

мне особенно нравится, что эти и другие подобные ярлыки могут быть объединены и использованы в вводных заявлений, таких как

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

(работ)

Однако, я не смог найти ярлык или функциональный эквивалент оператора while, который работает в круглых скобках. Что-то подобное существует?

Я пытался использовать нормальное заявление, а внутри скобок, но я получил ошибку

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

(не работает)

Я знаю, что выше, можно переписать в более длинной форме, как так

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

(работ)

Но иногда я действительно предпочитаю я nline сокращает эквивалент while, а не длинную версию. Есть ли способ сделать это?

+1

Пример «Более длинная форма» имеет ту же длину, что и «более короткий» пример, за исключением форматирования в белом пространстве. Единственное различие заключается в правильном использовании фигурных скобок вместо parens. –

+2

Ваш цикл while может или не может закончиться. Если вы передадите строку, состоящую из 161 + непространственных символов, вы никогда не покинете цикл while. Во всяком случае, я не уверен, почему вы его зацикливаете; replace получит весь экземпляр символа в одном вызове. Кроме того, похоже, что у вас есть синтаксическая ошибка в вашей однострочной версии. –

+1

@SteveH. Я думаю, что дело в том, что он хочет использовать оператор запятой вместо оператора return – Paulpro

ответ

4

Вы можете использовать рекурсию:

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

const trimmedStrings = array.map(cutSpace) 
+0

BTW Может ли кто-нибудь уточнить, является ли мой пример хорошим кандидатом для правильной оптимизации хвостового вызова, или я должен отрицать предикат и вызывать 'cutSpace' в выражении else? –

+2

Это вызов хвоста, независимо от того, в какую ветку вы его положили. – Bergi

+0

@ Bergi спасибо :) –

-2

Если вы делаете одну команду в цикле, вы можете использовать для цикла;

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

Так почему же это проголосовало? Похоже, что он отвечает на вопрос и, по-видимому, является самой компактной версией. – DSchnellDavis

+0

Ничего, я понял. Это потенциально умная идея, но она не работает. Когда я попытался использовать это в заключении в скобки, у меня возникла ошибка, как и у оператора while. – DSchnellDavis

0

Существует несколько функций, подобных этому. Для примера, который вы дали, он выглядит примерно так, как будто вы пытаетесь имитировать map function Array, который позволяет создавать массив из преобразованных элементов.

Пример:

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

Это будет возвращать новый массив каждой строки с пробелами удалены (в общем, ноту, которая функционирует модифицировать по сравнению с вызывающей производство новой, трансформированной версия .replace() функция. создает новую строку.).

Array prototype имеет несколько функций быстрого доступа для их итерации по ним, и их можно использовать для простого объединения сложных преобразований и дериваций. Map + Reduce - довольно часто используемая комбинация.

Я не знаю никаких других видов «синтаксического сахара» для циклов, кроме ярлыков итераций (ну, технически для цикла является одним).

0

Это не может быть короче, но функционален:

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);

Я изменил 160 до 2 и использовали map вместо forEach, чтобы сделать его проще показать.

+0

Назначение 'e' также не является функциональным, не так ли? – Bergi

+0

@Bergi Конечно, удаление этого задания сокращает код. Я просто использовал это, чтобы продемонстрировать, что более длинная версия OP ничего не делает, поскольку нет назначения. – Paulpro

2

Мне особенно нравится, что эти и другие подобные ярлыки могут быть объединены и использованы в вводных заявлениях, такой как

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

(работы)

Что? В каком качестве этот код «работает»? Если бы я увидел этот код в обзоре, я бы сразу его отклонил.

  • Внешняя мутация состояния в предикате?
  • Внутри петли, тем не менее?
  • Не стоит упомянуть ни a, ни b.
  • Не говоря уже круглые скобки и замыкающие e * x выражение полностью выброшены, тоже ... (?)

Это настолько плохо, это больно.

Я пытался использовать нормальное заявление, а внутри скобок, но я получил ошибку

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

(не работает)

Ну это ошибка синтаксиса. Вы пытались использовать заявление , где допускаются только выражения. Такие вещи, как if, for, while, doПоложения. Вы не можете поставить оператор в выражении (...). Даже если вы могли бы использовать здесь выражение while, код все равно не будет do ничего. Каждое вычисление полностью отбрасываются

Я знаю, что выше, можно переписать в более длинной форме, как так

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

(работ)

"работает"? Как это работает? Синтаксически все в порядке, но на самом деле это не do.

  • Строки неизменны так String.prototype.replace не мутирует e, как я думаю, что вы визуализации это делает.
  • Array.prototype.forEach игнорирует возвращаемое значение в функции итератора
  • Array.prototype.forEach не имеет возвращаемого значения своего собственной

Я могу только предположить, что вы имеете в виду, чтобы сделать что-то вроде этого

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

Вы видите разницу? Я использую e = e.replace(...), потому что replace не мутирует входную строку на месте. Кроме того, мой итератор на самом деле что-то делает со значением - console.log, немой, как может быть

Кажется, что вы, возможно, не знаете о Array.prototype.map. Подобно replace, map не будет мутировать исходный вход - вместо этого возвращается новое значение. Поэтому на этот раз мы присваиваем возвращаемое значение карты к новой переменной, output и войти, что, когда мы сделали

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" 
 
// ]

Ни один из этих двух последних фрагментов кода являются плохо , Первый имеет побочный эффект ввода-вывода (console.log в forEach), но второй полностью чист и полностью функциональен. Нет ничего плохого в местных мутациях, и нет ничего плохого в использовании while в ваших программах, особенно если учесть, что JavaScript не поддерживает JavaScript, что я знаю о поддержке оптимизации хвостовых вызовов. Рекурсия на самом деле не является пчелиными колени в земле JS.

+2

Так что я действительно не отвечаю на ваш вопрос, вместо этого этот ответ объясняет, что вы в основном лаяли неправильное дерево. Очевидно, что ваша главная цель - сохранить код «коротким», во всяком случае - это шутка с учетом правильной структуры, гораздо важнее умного синтаксического супа, который появляется в фрагментах кода в вашем вопросе. В 'for' или' while' нет ничего неправильного, и вы можете поддерживать функциональные интерфейсы в своей программе, даже некоторые функции могут локально использовать такие заявления. TL: DR; не пытайтесь обойти эти вещи, особенно * ради краткости. – naomik

+1

Спасибо, что поместили мои мысли в письменный текст :-) – Bergi

 Смежные вопросы

  • Нет связанных вопросов^_^