Поради щодо гольфу в JavaScript


133

Які загальні поради щодо гольфу в JavaScript? Я шукаю ідеї, які можна застосувати до проблем із гольфом взагалі, які принаймні дещо специфічні для JavaScript (наприклад, "видалити коментарі" - це не відповідь).

Примітка. Також дивіться Поради щодо гольфу в ECMAScript 6 і вище


Мене насправді цікавило, чи можна розміщувати змінні в глобальному (економить var)? І чи повинен код JavaScript для гольфу бути функцією або виводити щось безпосередньо? Я чесно думаю, що це може мати велике значення.
pimvdb

1
@primvdb: Це дозволено, але ви повинні бути обережними, оскільки це може викликати побічні ефекти, якщо функція викликається кілька разів і вона маніпулює глобальними змінними, або якщо це рекурсивна функція.
mellamokb

Відповіді:


108

Фантазія для петель

ви можете використовувати стандарт для циклу нестандартними способами

for ( a; b; c )

по суті еквівалентний:

a;
while ( b )
{
  ...
  c;
}

тому хороший трюк - написати свій код із whileциклом, а потім розділити його на a,b,cчастини в forциклі.

Я написав кілька прикладів :

for(x=y=n;!z;x--,y++)z=i(x)?x:i(y)?y:0
for(a=b=1;b<n;c=a+b,a=b,b=c);

Закріпіть свої сетери

Якщо ви ініціалізуєте або скидаєте кілька значень, зв’яжіть це значення на всі змінні, які потребують його:

a=b=1;

Неявне кастинг

Не перевіряйте свої типи, просто використовуйте їх такими, якими вони є. parseInt()вартість 10символів. Якщо вам потрібно викинути рядок, будьте креативними:

a='30';
b='10';
c = a + b; //failure
c = parseInt(a) + parseInt(b) //too long

c = -(-a-b); //try these
c = ~~a+~~b;
c = +a+ +b;
c = a- -b;

Уникайте напівколонок

У JavaScript є автоматична вставка напівколонки. Використовуйте його часто і добре.

Однолінійні

Збережіть на дужках, засунувши якомога більше в окремі рядки або параметри:

a( realParam1, realParam2, fizz='buzz' )

Оператори збільшення / зменшення

a = a - 1;
foo(a);

і

foo(a);
a = a - 1;

легко можна переписати як

foo(--a);

і

foo(a--);

відповідно.

Використовувати thisабо selfзамість цього windowв глобальному контексті

самооцінка 2 заощадження символів.

Використовуйте позначення дужок для повторного доступу до властивостей

Це, безумовно, акт балансування між довжиною імені властивості та кількістю доступу. Замість того, щоб дзвонити a.longFunctionName()з нотацією крапками двічі, коротше зберегти ім'я та викликати функцію через нотацію дужок:

a.longFunctionName(b)
a.longFunctionName(c)
//42

-vs-

a[f='longFunctionName'](b)
a[f](c)
//34

це особливо ефективно при таких функціях, до document.getElementByIdяких можна звести d[e].

Примітка:

За допомогою позначення дужок вартість вказується 6 + name.lengthсимволами вперше. Кожен наступний доступ має вартість 3символів.

Для позначення точок усі звернення коштують name.length + 1(+1 для .) символів.

Використовуйте цей метод, якщо 6 + name.length + (3 * (accesses - 1)) < accesses * (name.length + 1).

len = довжина назви властивості
i = мінімальний доступ для використання

len | i 
========
1   |  
2   |  
3   | 7 
4   | 4 
5   | 3 
6   | 3 
7   | 3 
8+  | 2 

Кількість доступу також може охоплювати декілька об'єктів. Якщо ви отримуєте доступ до .length4 або більше разів на різних масивах, ви можете використовувати ту саму змінну, що містить рядок 'length'.


5
c = ~~a-~~bповинно бути c = ~~a+~~b. Крім того , ви можете неявно в цілому , використовуючи |0, наприклад Math.random()*6|0.
mellamokb

7
Це дешевше примусити рядок до числа з оператором unary plus. Якщо aі bє рядками, ви можете зробити +a+bїх перетворення в число і додати їх.
Пітер Олсон

8
Я клянусь, що d- -bколись буду використовувати у своєму коді ...
Джон Дворак

4
+ a + b не працює (принаймні, на моєму ...) // a = "1", b = "1", + a + b // дає "11"
imma

2
Для "Використовувати Array-Access для повторних викликів функції", якщо ви використовуєте функцію більше ніж два рази на одному об'єкті , дещо коротше - призначити функцію новому члену, наприкладa.f=a.longfunctionname;a.f(b);a.f(c);a.f(d)
Мартін Ендер,

131

Розбиття на числа, щоб зберегти лапки:

"alpha,bravo,charlie".split(",") // before
"alpha0bravo0charlie".split(0)   // after

2
Він працює, і я використовував його для кількох цифр.
Isiah Meadows

12
Lol це насправді досить креативно
NiCk Newman

9
в ES6 це вже не має значення, ви можете просто зробити.split`...`
David Archibald

"alpha,bravo,charlie".split`,`
Kamil Kiełczewski

56

Використовуйте оператор комами, щоб уникнути дужок (також стосується C ):

if(i<10)m+=5,n-=3;

Замість

if(i<10){m+=5;n-=3}

що на один символ довше.


2
Чи потрібна крапка з комою в кінці першого зразка?
wjl

4
@wjlafrance: Це було б не потрібно лише, якщо він знаходиться в кінці однолінійки.
mellamokb

48

Коротше генерація випадкових чисел

Якщо вам потрібен випадковий булевий ( 0або 1):

new Date&1 // equivalent to Math.random()<0.5

Якщо вам потрібно випадкове ціле число 0 <= n < 1337:

new Date%1337 // equivalent to Math.floor(Math.random()*1337))

Це працює, тому що a Dateзберігається внутрішньо в JavaScript як кількість мілісекунд з епохи, тому new Dateпримусовується до цього, 123somebignumber456коли ви намагаєтеся зробити на ньому цілу математику.

Звичайно, ці "випадкові" числа справді не будуть такими випадковими, особливо якщо ви їх викликаєте кілька разів за швидкою послідовністю, тому майте це на увазі.


1
Щойно згадав цю відповідь, читаючи Більш неправдиві програмісти вірять про час : «21. Якщо ви створите два об’єкти дати поруч один з одним, вони представлятимуть один і той же час. (фантастичний генератор Гейзенбуга) ” .
Себастьян Саймон

39

Ви можете використовувати об'єктну буквальну форму get / set, щоб уникнути використання ключового слова function.

var obj = {
  get f(){
    console.log("just accessing this variable runs this code");
    return "this is actually a function";
  },
  set f(v){
    console.log("you can do whatever you want in here, passed: " + v);
  }
};

1 && obj.f; // runs obj.[[get f]]
obj.f = Infinity; // runs obj.[[set f]](Infinity)

частина геттера / сетера була дуже корисною. thx
gion_13

1
Насправді, ще кращим є об’єктний метод, якщо ви використовуєте його <= 2 рази. З іншого боку, функції стрілок набагато кращі для скорочення символів, оскільки вони служать майже одній цілі, а заняття рідко корисні в коді для гольфу.
Ісія Медоуз

якщо підтримка важлива, функції стрілок не підтримуються у fx. тобто11
Джим

35

Цей менш відомий і менш використовуваний, але може бути вражаючим, якщо використовувати його у правильній ситуації. Розглянемо функцію, яка не бере аргументів і завжди повертає інше число при виклику, і повернене число буде використовуватися в обчисленні:

var a = [ 
    Math.random()*12|0,
    Math.random()*11|0,
    Math.random()*10|0,
    /* etc... */ 
];

Ви можете скоротити цю функцію, використовуючи однобуквене ім'я змінної:

var r=Math.random,a=[r()*12|0,r()*11|0,r()*10|0,r()*9|0,r()*8|0,r()*7|0,r()*6|0,r()*5|0];

Кращий спосіб зменшити довжину - це зловживання valueOf, що дозволяє заощадити 2 символи на виклик. Корисно, якщо ви викликаєте функцію більше 5 разів:

var r={valueOf:Math.random},a=[r*12|0,r*11|0,r*10|0,r*9|0r*8|0,r*7|0,r*6|0,r*5|0];

8
Або ви можете зробити так, як будь-який із цих: let a=[5,6,7,8,9,10,11,12].map(x=>x*Math.random()|0)або let a=Array(7).map((_,i)=>i*Math.random()|0+5), відповідно, 36 або 42 байти, збережені.
Іся Медоуз

Чи можна замінити r()або зробити його коротшим?
NiCk Newman

3
r={valueOf:Math.random}Це просто геніальний: D
ETHproductions

1
@Isiah, ну так, це можна зробити зараз :-D
Енді Е

32

Користуючись операторами короткого замикання

Замість тривалих ifзаяв або використання термінальних операторів ви можете скористатися &&і ||скоротити код. Наприклад:

var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);

return match ? decodeURIComponent(match[1].replace(/\+/g, ' ')) : null;

може стати

var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);

return match && decodeURIComponent(match[1].replace(/\+/g, ' '));

||Оператор часто використовується таким чином , для установки по замовчуванням:

evt = evt || window.event;

Це те саме, що писати

if (!evt)
    evt = window.event;

Створення рядків, що повторюються, за допомогою Array

Якщо ви хочете ініціалізувати довгий рядок певного символу, ви можете зробити це, створивши масив довжиною n + 1 , де n - кількість разів, яку ви хочете повторити символ:

// Create a string with 30 spaces
str = "                              ";

// or
str = Array(31).join(" ");

Чим більше рядок, тим більша економія.

Розбір номерів

Використовуйте +та ~оператори замість parseFloat()або parseInt()при об'єднанні типу рядка, який є лише числом, до типу номера:

var num = "12.6";
parseFloat(num) === +num;  // + is 10 characters shorter than parseFloat()

var num2 = "12"
parseInt(num2) === +num2;   // + is 8 characters shorter than parseInt()

var num3 = "12.6"
parseInt(num3) === ~~num3;  // ~~ is 7 characters shorter than parseInt()

var num4 = "12.6"
parseInt(num4) === num4|0;  // |0 is 7 characters shorter than parseInt()

Будьте обережні, але інші типи можуть поєднуватися з цими операторами (наприклад, trueвони стануть 1) порожньою рядком або рядком, що містить просто пробіл 0. Однак це може бути корисним за певних обставин.


6
+1 для створення рядків, що повторюються, за допомогою Array - не думав про це.
mellamokb

4
Для створення рядків, що повторюються, в ES6 ви можете використовуватиstr.repeat(count)
Oriol

26

Провести ініціалізацію змінної змінної у виклику prompt () для отримання вводу користувача

n=prompt(i=5);     // sets i=5 at the same time as getting user input

замість використання

n=prompt();i=5;

Як побічний ефект, він відображає вхідне значення у вікні підказки, зберігаючи 1 символ.


12
Це також може бути застосоване до будь-якої функції, яка не приймає аргументи.
Кейсі Чу

3
Навіть коли функція приймає аргументи, вона може бути корисною, як [1,2,3].join('',i=5)у випадках, коли вона зберігає пару дужок.
DocMax

3
@DocMax: Ви можете використовувати для цього оператор комах - i=5,[1,2,3].join().
Конрад Боровський

@GlitchMr: Я міг би, але це не рятує жодних символів. Я згоден, що більшу частину часу це буде чистіше. Я думаю, що все ще можуть бути випадки, коли моє замовлення могло б зберегти чародійку, хоча наразі я не можу придумати її (і я цілком можу помилятися).
DocMax

@DocMax Тільки якщо ви скористаєтеся ASI.
Ісія Медоуз

24

Поєднайте вкладені петлі:

// before:
for(i=5;i--;)for(j=5;j--;)dosomething(i,j)

// after:
for(i=25;i--;)dosomething(0|i/5,i%5)

Приклад з різними значеннями для i/ j:

// before:
for(i=4;i--;)for(j=7;j--;)dosomething(i,j)

// after:
for(i=28;i--;)dosomething(0|i/7,i%7)

(Я відредагував а) другорядний друк, але дуже розумний! Зауважте, що це буде працювати лише у вкладених петлях однакової довжини (якщо я не помиляюся).
Каміло Мартін

1
@CamiloMartin Ні, петлі не повинні бути однакової довжини. Отримане число ітерацій є, i*jі оператори поділу / модуля отримують індивідуальні значення iі j.
тихість

@ user113215 Ви праві, приголомшливі! :) Я відредагував відповідь, щоб включити приклад.
Каміло Мартін

23

Ярлики Unicode

Якщо ви використовуєте пекельну вбудовану власність у великому виклику з гольфу, ви можете псевдонімити кожне майно на еквівалент одного символу:

[Math,Number,S=String,Array].map(b=>
    Object.getOwnPropertyNames(b).map((p,i)=>
        b.prototype[S.fromCharCode(i+248)]=b[p]
    )
)

Після виконання коду вище, ви можете використовувати його так:
"foo".Č(/.*/,'bar') // replaces foo with bar

Це коштує 118 байт, тому може не бути корисним у певних ситуаціях

Це може залежати від браузера, і я не впевнений, чи він коротший with(Array){join(foo),...}або визначає змінні як використовувані властивості, with(Array){j=join,m=map...}але все-таки варто згадати.

    Math        Number              String              Array

ø   toSource    prototype           prototype           prototype
ù   abs         NaN                 quote               join
ú   acos        POSITIVE_INFINITY   substring           reverse
û   asin        NEGATIVE_INFINITY   toLowerCase         sort
ü   atan        MAX_VALUE           toUpperCase         push
ý   atan2       MIN_VALUE           charAt              pop
þ   ceil        MAX_SAFE_INTEGER    charCodeAt          shift
ÿ   clz32       MIN_SAFE_INTEGER    contains            unshift
Ā   cos         EPSILON             indexOf             splice
ā   exp         isFinite            lastIndexOf         concat
Ă   floor       isInteger           startsWith          slice
ă   imul        isNaN               endsWith            filter
Ą   fround      toInteger           trim                isArray
ą   log         parseFloat          trimLeft            lastIndexOf
Ć   max         parseInt            trimRight           indexOf
ć   min         length              toLocaleLowerCase   forEach
Ĉ   pow         name                toLocaleUpperCase   map
ĉ   random      arguments           normalize           every
Ċ   round       caller              match               some
ċ   sin                             search              reduce
Č   sqrt                            replace             reduceRight
č   tan                             split   
Ď   log10                           substr  
ď   log2                            concat  
Đ   log1p                           slice   
đ   expm1                           fromCharCode    
Ē   cosh                            fromCodePoint   
ē   sinh                            localeCompare   
Ĕ   tanh                            length  
ĕ   acosh                           name    
Ė   asinh                           arguments   
ė   atanh                           caller  
Ę   hypot           
ę   trunc           
Ě   sign            
ě   cbrt            
Ĝ   E           
ĝ   LOG2E           
Ğ   LOG10E          
ğ   LN2         
Ġ   LN10            
ġ   PI          
Ģ   SQRT2           
ģ   SQRT1_2         

Я використовую google chrome, і все це дає не визначений характер.
SuperJedi224

Він повинен бути дуже firefox тоді. Вибачте за незручності.
bebe

Чому це всі спеціальні персонажі? Чому б просто не використовувати друкований ASCII? (простіше набрати, надійніше та лише 1 байт для гри в гольф)
Cyoce

Це насправді не працює, Mathоскільки він не має .prototypeатрибута. Видаляючи Math, проте, мені вдалося переграти це до 114-байтового фрагмента, який призначає їх однобайтовим літерам. Ви можете знайти його тут .
ETHproductions

1
Ви також можете розіграти моє рішення на 106 байт за рахунок переміщення всіх цих властивостей у діапазон À- ÿякий досі становить 1 байт у кодуванні ISO-8859-1 (який підтримує JS). У Firefox 50 це, на жаль, ставить .localeCompareметод ×, але це, як правило, не повинно бути проблемою. джерело
ETHproductions

22

Перетворення whileциклу в forцикл часто рівнозначне:

while(i--);
for(;i--;);

Але друга форма може поєднувати ініціалізацію змінної:

i=10;while(i--);
for(i=10;i--;);

Зауважте, друга форма на один символ коротша, ніж перша.


6
Або, ще краще, просто використовувати для петель. Насправді не існує жодного випадку, коли використання циклу призводить до більшого коду, наскільки я пережив.
Ісія Медоуз

22

Виняток зловживань

у випадку, якщо літеральні рядки / символи заборонені, ви можете використовувати блок спробувати вловлювання:

try{something0}catch(e){str=e.message.split(0)[0]}

тепер strдорівнює"something"

якщо потрібно більше рядків, ви можете зв’язати це числом (наприклад, нулі)

try{something0foo0bar0}catch(e){arr=e.message.split(0)}

тепер arrдорівнює["something", "foo", "bar", " is not defined"]


18

Якщо ви ініціалізуєте змінну до 1кожної ітерації циклу (наприклад, скидання змінної у зовнішній цикл для внутрішнього циклу), наприклад: (з моєї відповіді на це запитання ):

for(j=n-2;p=1,j++<=n;r|=p)for(i=1;++i<j;)p=j%i?p:0;
          ^^^^

Оскільки результат такої умови, як завжди, j++<=nє 1її правдою, ви можете просто призначити умову безпосередньо змінній (тому що, коли вона стане помилковою, цикл перестане виконуватись і більше не матиме значення):

for(j=n-2;p=j++<=n;r|=p)for(i=1;++i<j;)p=j%i?p:0;
          ^^^^^^^^

Зазвичай за допомогою цього методу можна зберегти 2 символи . Звертається до @ugorenідеї в коментарях до цієї відповіді.


Для іншого прикладу я також застосував цю хитрість до своєї відповіді тут із виразом w=r=++c<S.lengthу моїй зовнішній частині для циклу, заощадивши загалом 4 символи.



17

Якщо вам потрібно перевірити наявність NaN, не використовуйте isNaN(x), але використовуйте x!=x, що коротше і також працює.

if(isNaN(x)){
if(x!=x){

Зауважте, що це працює лише у випадку typeof(x) === "number", якщо ; якщо це, наприклад, рядок, isNaN("string")повертається true, але "string" != "string"повертається false. Дякую Cyoce за те, що вказав на це!


2
Це геніальне використання цієї химерності. +1
ETHproductions

Попередження: це не завжди рівнозначно: isNaN("string")повернення true, тоді як "string"!="string"повернення false(очевидно)
Cyoce

@Cyoce Добрий момент, дякую! Я відредагував свою відповідь.
ProgramFOX

У багатьох випадках ви навіть можете піти if(!x){, якщо ви виявите це NaNявно.
Hohmannfan

1
Передача xчисельності +x!=+xробить його еквівалентним isNaN(x), але все ж на 2 символи коротше. Потім, +"string"!=+"string"повертає істину.
Томаш Лангкаас

15

Сума масиву / продукт / коефіцієнт

ES5 : 17 байт

eval(a.join('+'))

ES6 : 15 байт

eval(a.join`+`)

Звичайно, ви можете поміняти місцями на +все, що завгодно, наприклад, *на товар або /на частку.


14

Використовуйте побітну операцію, щоб округлити число до нуля:

// do this
T=Math.random()*6+1|0

// or do this
T=~~(Math.random()*6+1)

(Джерело: Випадкові наконечники кісток )

Пріоритет оператора визначає, який термін буде коротшим у вашій програмі.


2
Це також може бути використане для об'єднання рядкового вводу в ціле число, тобто n=prompt()|0.
mellamokb

1
бітовий розряд
vsync

@vsync: Дивно. Мені здається, що на Chrome 11.0.696.77 швидкість в математиці приблизно вдвічі швидша, ніж біт.
mellamokb

дуже дивно. для мене вони обоє більш-менш однакові швидкості і надшвидкі в Chrome, але у FF Math.floorпобітовий куди набагато швидше, ніж у Chrome, і страшенно повільний. Більш того, я б не сказав.
vsync

Щоб коментарі були актуальними, у поточному Fx вони швидко і приблизно рівні. Не те, що це, мабуть, вузьке місце в першу чергу, порівняно з оточуючим кодом ...
FireFly

14

Підказка I

Ви можете зберегти 1символ під час циклу, змінивши iостанній раз, що використовується:

//not so god
for(i=0;i<3;i++){
  alert(i);
}

//best
for(i=0;i<3;){
  alert(i++);
}

Примітка:-- теж працює (але відповідно змініть цикл, щоб уникнути нескінченного циклу)


Підказка для циклу II

Існують певні сценарії, коли ви можете зберегти один символ, граючи з оператором збільшення та значеннями:

for(i=0;i++<9;)
for(i=0;++i<10;)

Примітка: вам потрібно звернути увагу, коли, наприклад 0 to -1. і 9 to 10, 99 to 100так пограйте, поки не знайдете спосіб зберегти персонажа


13

Використовуйте ^замість !=або ==при порівнянні з цілим числом

//x!=3?a:b
  x^3?a:b

//x==3?a:b
  x^3?b:a

Замініть дзвінки до вбудованих функцій Math більш короткими виразами

//Math.ceil(n)
  n%1?-~n:n

//Math.floor(n)
  ~~n
  0|n

//Math.abs(n)
  n<0?-n:n

//Math.round(n)
  n+.5|0

//Math.min(x,y)
  x<y?x:y

//Math.max(x,y)
  y<x?x:y

2
Крім того, ви можете просто використовувати -замість !=цілих чисел; Наприклад, n!=1?a:bбуло б рівнозначноn-1?a:b
vrugtehagel

10

Щось варто зазначити, що ви можете використовувати рядок замість нуля в деяких випадках, щоб зберегти пару байтів тут і там у циклі:

s='';for(i=0;i++<9;)s+=i
for(i=s='';i++<9;)s+=i
// s="123456789", i=10

1
Я раніше спробував "" ++ у консолі, цікавившись, чи буде вона працювати, звичайно, спочатку вона повинна бути в змінній. Дякую!
Вартан

10

Дуже простий, навіть так, ніхто про це не згадував.

Якщо ви використовуєте Math.min()або Math.max()ви можете зберегти 6 символів, виконавши це:

Math.min(a,b)  // 13 chars
a<b?a:b        //  7 chars

Math.max(a,b)
a>b?a:b

10

Округлення

Я знаю, що альтернативи Math.floor()були розміщені, але що робити з іншими?

Підлога:

Math.floor(x) //before
0|x           //after

Округлення:

Math.round(x) //before
0|x+.5        //after

Стеля:

Math.ceil(x) //before
x%1?-~x:x    //after - credits to @Tomas Langkaas

1
Зауважте, що 0|x+1просто додається 1, якщо число, для якого потрібно знайти стелю, вже є цілим числом. (В основному) безпечна альтернатива є 0|x+1-1e9, але це лише на три байти коротше.
ETHproductions

@ETHproductions ти не маєш на увазі 0|x+1-1e-9?
Mama Fun Roll

Ой, так. Дякуємо, що вказали на це. (Чомусь я не можу зробити @ (ваше ім'я користувача) ...)
ETHproductions

Можливо, тому, що мої ім’я користувача перевернуті :)
Mama Fun Roll

1
Для стелі x%1?-~x:x(9 символів) - краща альтернатива. Однак, як альтернативи підлогових покриттів 0|xі ~~x, це працює тільки для позитивних чисел.
Томаш Лангкаас

9

У випадках, коли ви використовуєте потрійний оператор для вибору між двома числами , а умовний - булевим чи числом 1 or 0 , замість цього ви можете робити математичні операції:

(x ? num1 : num2) conclusions:

    1)if num1 equals num2, there ARE savings
    2)if num1 is (+1) or (-1) than num2, there ARE savings
    3)if either num1 or num2 equals to 0, there ARE savings
    4)it is MORE LIKELY to find greater savings on num1>num2 instead of num1<num2
    5)in method (*A) and (*B), savings are NOT GUARANTEED

    a)num1>num2
        i)(num1==(num2+1))
            ex1: (x?5:4) to (x+4)
            ex2: (x?8:7) to (x+7)
        ii)num2==0
            ex1: (x?3:0) to (x*3)
            ex2: (x?7:0) to (x*7)
        iii)
            (*A) or (*B) //one might be shorter

    b)num1<num2
        i)((num1+1)==num2)
            ex1: (x?4:5) to (5-x)
            ex2: (x?7:8) to (8-x)
        ii)num1==0
            ex1: (x?0:3) to (!x*3)
            ex2: (x?0:7) to (!x*7)
        iii)
            (*A) or (*B) //one might be shorter

    c)num1==num2
        i)
            ex1: (x?5:5) to (5)
            ex2: (x?-3:-3) to (-3)

    (*A) use ((x*(num1-num2))+num2)
        ex1: (x?8:4)   to ((x*4)+4)
        ex2: (x?4:8)   to ((x*-4)+8)

        ex3: (x?6:-4)  to ((x*10)-4)
        ex4: (x?-4:6)  to ((x*-10)+6)

        ex5: (x?4:-6)  to ((x*10)-6)
        ex6: (x?-6:4)  to ((x*-10)+4)

        ex7: (x?-5:-9) to ((x*4)-9)
        ex8: (x?-9:-5) to ((x*-4)-5)

    (*B) use ((!x*(num2-num1))+num1)
        ex1: (x?8:4)   to ((!x*-4)+8)
        ex2: (x?4:8)   to ((!x*4)+4)

        ex3: (x?6:-4)  to ((!x*-10)+6)
        ex4: (x?-4:6)  to ((!x*10)-4))

        ex5: (x?4:-6)  to ((!x*-10)+4)
        ex6: (x?-6:4)  to ((!x*10)-6)

        ex7: (x?-5:-9) to ((!x*-4)-5)
        ex8: (x?-9:-5) to ((!x*4)-9)

Примітка: На додаток до цього, вам потрібно буде видалити непотрібні 0-, +0, і +-т.д.

Примітка2: є окремий випадок, коли (x) !== (x?1:0), як і xналежить, typeof === "number"він повинен працювати. Однак у випадку (-x)це працює просто чудово.

Примітка3: Якщо ви не знайдете заощадження, просто скористайтеся першою(x?y:z)

Раніше я вважав, що метод B ніколи не може перемогти A, проте існують винятки:

(x?97:100) //original

(-3*x+100)
(3*!x+97)

Я створив проект github, який робить спрощення для нас ( jsFiddle demo )


@ ajax333221 void 0(це не функція, а ключове слово) - це не значення, воно просто повертається undefined.
Каміло Мартін

@CamiloMartin Ви маєте рацію, також я бачу сенс у цій відповіді, однак aмає бути або 1, або 0, щоб воно працювало
ajax333221

@ ajax333221 Так, насправді найцікавіше, що стосується гольф-коду для мене, це те, що більшість найкращих трюків працюють лише для тієї конкретної речі, яку ти робиш, і хтось почуває себе таким розумним, щоб знайти один із цих кутових справ із кутовими рішеннями: D Таким чином, вам не потрібно видаляти коментарі ...
Camilo Martin

9

tl; dr: Використовуйте функції ES6!

Функції стрілки

Документ: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/arrow_functions
Приклад:

s = x => x*x
// s = function (x) {
//   return x * x;
// }

Про функції стрілок вже згадувалося 13 жовтня 1313 о 15:42 . Але це for.. ofкруто. Навіть коротше for each.. in.
манантська робота

2
Синтаксис розуміння масиву здається помилковим. За документацією має бути як у Python : b = [s(x) for (x of a)].
манантська робота

@manatwork Вищезазначені зразки відмінно спрацьовують у відповіді Traceur
Florent

Поняття про Traceur не маю, але ви згадали про ECMAScript і вказали на документацію Mozilla. І розуміння масиву в жодному з них не виглядає так, як ви це написали.
манатство

1
Розуміння масиву насправді було витягнуто на середину.
Іся Медоуз

9

Зловживайте літералами

Нещодавній зразок. Перевірте, чи "c"це великі чи малі регістри, не має значення, якщо не літера

"c"<{} // returns false, lower case
"C"<{} // returns true, upper case

3
Як це працює?
Корови кракають

2
@Cowsquack String({})дає "[object Object]".
Денніс

8

Як порівняти число за допомогою того, як числа перетворюються на булеві:

Якщо ви збираєтеся перевірити, чи щось дорівнює позитивному числу , ви можете відняти цю суму і відмінити те, що було всередині ifта elseблоки:

//simplified examples:
x==3?"y":"n"; <- 13 Chars
x-3?"n":"y"; <- 12 Chars

//expanded examples:
if(x==3){
    yes();
}else{
    no();
}

if(x-3){
    no();
}else{
    yes();
}

І якщо ви хочете порівняти з від’ємним числом (* відмінним від -1), вам просто потрібно додати це число замість віднімання.

* ну, ви можете, звичайно, використовувати x.indexOf(y) + 1, але в особливому випадку у -1вас є можливість використовувати ~x.indexOf(y)замість цього.


8

Використовуйте нестандартну функцію «закриття виразів» Mozilla, щоб зберегти багато символів у сценарії, який потрібно працювати лише в двигунах SpiderMonkey / Firefox або Rhino. Наприклад,

function foo(){return bar}

стає

function foo()bar

Дивіться сторінку "Переповнення стека" для отримання таких подібних хитрощів.


2
Це не Javascript. Це ПРОСТІРНА СТАНЦІЯ !!!
Томас Едінг

1
ECMAScript 6 на допомогу! ->bar
Ри-

5
ECMAScript 6:, за let foo = () => bar;іронією долі коротший, ніж код для гольфу вище.
Ісія Медоуз

1
ECMAScript 6:, foo=_=>barнавіть коротше.
ETHproductions

це посилання розірвано.
Cyoce



8

Трансформація в булеву :

if(b){b=true}else{b=false}
b=b?true:false;
b=b?!0:!1;
b=!!b;

Примітка: Ця зміна 0, "", false, null, undefinedі NaNдо false(все інше true)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.