JavaScript에서의 골프 팁


133

JavaScript에서 골프를 치기위한 일반적인 팁은 무엇입니까? JavaScript와 관련이있는 코드 골프 문제에 일반적으로 적용 할 수있는 아이디어를 찾고 있습니다 (예 : "댓글 제거"는 답이 아닙니다).

참고 : ECMAScript 6 이상의 골프 팁 도 참조하십시오 .


실제로 궁금합니다. 글로벌 (저장 var) 에 변수를 넣을 수 있습니까? 그리고 JavaScript 골프 코드는 함수이거나 직접 출력해야합니까? 솔직히 이것이 큰 차이를 만들 수 있다고 생각합니다.
— pimvdb

1
@primvdb : 허용되지만 함수가 여러 번 호출되고 전역 변수를 조작하거나 재귀 함수 인 경우 부작용을 일으킬 수 있으므로주의해야합니다.
— mellamokb

답변:


108

팬시 포 루프

비표준 방식으로 표준 for 루프를 사용할 수 있습니다

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 

액세스 수는 여러 개체에 걸쳐있을 수도 있습니다. .length다른 배열에서 4 번 이상 액세스 하면 string을 보유한 동일한 변수를 사용할 수 있습니다 'length'.


5
c = ~~a-~~b이어야합니다 c = ~~a+~~b. 또한, 암시 적으로 사용하여 정수로 캐스트 할 수 있습니다 |0예를 들어, Math.random()*6|0.
— mellamokb 2016 년

7
단항 더하기 연산자로 문자열을 숫자로 강제 변환하는 것이 더 저렴합니다. 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)
— Martin Ender


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

이것은 Date에포크 이후 밀리 초의 양으로 JavaScript에 내부적으로 저장되어 있기 때문에 작동하므로 정수 수학을 시도 할 때 new Date강제로 진행 123somebignumber456됩니다.

물론,이 "무작위"숫자는 실제로 임의적이지 않습니다. 특히 연속해서 여러 번 연속해서 호출하는 경우 명심하십시오.


1
프로그래머가 시간에 대해 더 많은 허위 사실 을 읽는 동안이 대답을 기억했습니다 . “21. 서로 바로 옆에 두 개의 날짜 개체를 만들면 같은 시간을 나타냅니다. (환상적인 Heisenbug 생성기)” .
— 세바스찬 시몬

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 번만 사용하는 경우 객체 방법이 훨씬 좋습니다. 반면, 화살표 기능은 거의 같은 목적으로 사용되므로 문자를 자르는 데 훨씬 효과적이며 클래스는 골프 코드에서 거의 유용하지 않습니다.
— Isiah Meadows

지원이 중요한 경우 fx에서는 화살표 기능이 지원되지 않습니다. ie11
— Jim Wolff

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

길이를 줄이는 더 좋은 방법은 abusing 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 바이트가 각각 저장됩니다.
— Isiah Meadows 2019

교체 r()하거나 더 짧게 만들 수 있습니까?
— NiCk Newman

3
r={valueOf:Math.random}그것은 천재입니다. : D
— ETHproductions

1
@Isiah, 그래, 넌 지금 할 수있어 :-D
— Andy E

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
Array를 사용하여 반복적 인 문자열을 만들기위한 +1-그것에 대해 생각하지 않았습니다.
— mellamokb 2016 년

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
인수를 허용하지 않는 함수에도 적용 할 수 있습니다.
— Casey Chu

3
함수가 인수를 허용하더라도 [1,2,3].join('',i=5)중괄호 쌍을 저장하는 경우 와 같이 유용 할 수 있습니다 .
— DocMax

3
@DocMax : 쉼표 연산자를 사용할 수 있습니다 i=5,[1,2,3].join().
— Konrad Borowski 2019 년

@GlitchMr : 할 수는 있지만 문자를 저장하지는 않습니다. 나는 대부분의 시간이 더 깨끗할 것이라는 데 동의합니다. 나는 지금 주문을 할 수는 없지만 내 주문으로 문자를 절약 할 수있는 경우가 여전히있을 수 있다고 생각합니다 (그리고 잘못되었을 수도 있습니다).
— DocMax

@DocMax ASI를 활용하는 경우에만 해당됩니다.
— Isiah Meadows 2018

24

중첩 된 for 루프를 결합하십시오.

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

사소한 오타이지만 매우 영리합니다! 이것은 길이가 같은 중첩 루프에서만 작동합니다 (잘못되지 않은 경우).
— Camilo Martin

1
@CamiloMartin 아니오, 루프의 길이가 같을 필요는 없습니다. 반복의 결과 숫자는 i*j상기 분할 / 모듈러스 연산자의 개별 값을 검색 i하고 j.
— quietmint

@ user113215 당신 말이 맞아요! :) 예제를 포함하도록 답변을 편집했습니다.
— Camilo Martin

23

유니 코드 단축키

큰 골프 도전에서 빌트인 속성의 지옥을 사용하는 경우 모든 속성의 별칭을 한 문자로 지정할 수 있습니다.

[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 크롬을 사용하고 있으며 모두 정의되지 않았습니다.
— SuperJedi224

매우 파이어 폭스 전용이어야합니다. 불편을 드려 죄송합니다.
— bebe

왜이 모든 특수 문자입니까? 왜 인쇄 가능한 ASCII를 사용하지 않습니까? (타이핑하기 쉽고, 더 안정적이며, 골프를 위해 1 바이트 만)
— Cyoce

속성 Math이 없기 때문에 실제로 작동 하지 않습니다 .prototype. 그러나을 제거 Math하면이를 1 바이트 문자에 할당하는 114 바이트 스 니펫으로 골프를 쳤습니다. 여기에서 찾을 수 있습니다 .
— ETHproductions

1
당신은 또한 골프 범위로 모든 속성을 이동시키는 비용으로 106 바이트 내 용액 À- ÿ여전히 (JS 지원)을 ISO-8859-1 인코딩 각각 1 바이트이다. Firefox 50에서는 불행히도이 .localeCompare방법을 사용 ×하지만 일반적으로 문제가되지는 않습니다. 출처
— ETHproductions

22

while루프를 루프로 변환하는 for것은 종종 동일합니다.

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

그러나 두 번째 형식은 변수 초기화를 결합 할 수 있습니다.

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

두 번째 형식은 첫 번째 형식보다 한 문자가 짧습니다.


6
또는 더 나은 방법은 for 루프를 사용하는 것입니다. 내가 경험 한 한 for 루프를 사용하여 더 큰 코드를 생성하는 경우는 실제로 없습니다.
— Isiah Meadows 2019

22

예외 남용

문자열 / 문자 리터럴이 금지 된 경우 try catch 블록을 사용할 수 있습니다.

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

지금 str과 동일"something"

더 많은 문자열이 필요한 경우 숫자로 묶을 수 있습니다 (예 : 0)

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해당 답변에 대한 의견의 아이디어를 존중합니다 .


또 다른 예를 들어, 외부 for 루프 의 표현식 으로 여기 에이 트릭을 적용 w=r=++c<S.length하여 총 4자를 절약했습니다.


18

Spidermonkey (현재) 특정 스크립트를 승인 할 수있는 경우 ECMAScript 6 화살표 기능을 사용할 수 있습니다 . 다음과 같은 코드를 작성하는 대신.

a.map(function(x){return x*2}) // function? return?

이렇게 짧게 만들 수 있습니다.

a.map(x=>x*2)

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")returns true, 반면에 "string"!="string"returns false(명백하게)
— Cyoce

@Cyoce 좋은 지적, 감사합니다! 내 답변을 편집했습니다.
— ProgramFOX

많은 경우 명시 적으로 if(!x){감지하는 경우 에도 갈 수 있습니다 NaN.
— Hohmannfan

1
xnumber (으)로 캐스팅하면와 +x!=+x같지만 isNaN(x)여전히 2 자 더 짧습니다. 그런 다음 +"string"!=+"string"true를 반환합니다.
— Tomas Langkaas

15

배열 합 / 곱 / 몫

ES5 : 17 바이트

eval(a.join('+'))

ES6 : 15 바이트

eval(a.join`+`)

물론 제품이나 지수 +등 원하는 것을 바꿀 수 있습니다 .*/


14

비트 연산을 사용하여 숫자를 0으로 반올림하십시오.

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

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

(출처 : 랜덤 주사위 팁 )

연산자 우선 순위 에 따라 프로그램에서 더 짧은 것이 결정됩니다.


2
이것은 또한 문자열 입력을 정수로 통합하는 데 사용될 수 있습니다 n=prompt()|0.
— mellamokb

1
bitwise는 math.floor와 비교할 때도 매우 빠릅니다 : jsperf.com/floor-vs-bitwise
— vsync

@vsync : 이상합니다. Chrome 11.0.696.77에서 math.floor가 비트 단위로 약 두 배 빠릅니다.
— mellamokb 2016 년

엄청 이상해. 나를 위해 그들은 Chrome에서 다소 속도가 같고 빠릅니다. 그러나 FF에서는 비트 단위가 Chrome보다 훨씬 빠르며 매우 Math.floor느립니다. 거의 사용해서는 안됩니다.
— 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.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

주목해야 할 것은 일부 인스턴스에서 0 대신 문자열을 사용하여 여기 저기에서 몇 바이트를 루프로 저장할 수 있다는 것입니다.

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

1
나는 콘솔에서 ""++를 시도해 보았을 지 궁금해 할 것이다. 물론 변수에 먼저 있어야한다. 감사!
— Vartan

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이지만 이것은 3 바이트 더 짧습니다.
— ETHproductions

@ETHproductions은 무슨 뜻 0|x+1-1e-9인가요?
— Mama Fun Roll 1

네 지적 해 주셔서 감사합니다. (어떤 이유로 @ (사용자 이름)을 할 수 없습니다 ...)
— ETHproductions

아마 내 사용자 이름 문자가 거꾸로 있기 때문에 :)
— Mama Fun Roll 1

1
천장의 경우 x%1?-~x:x(9 자)가 더 나은 대안입니다. 그러나 바닥재 대안 0|x및과 마찬가지로 ~~x양수에만 적용됩니다.
— Tomas Langkaas

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.
— Camilo Martin

당신이 맞다 @CamiloMartin, 또한 지금은 그러나,이 답변에 포인트를 참조 a작동하는 1 또는 0 중 하나를해야합니다
— ajax333221

@ ajax333221 예, 실제로 저에게 코드 골프에 관한 재미있는 점은 대부분의 최고의 트릭은 당신이하고있는 특정 일에 대해서만 작동한다는 것입니다. 방법, 당신은하지 않습니다 이 ... 댓글을 삭제
— 카밀로 마틴

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;
// }

화살표 기능은 이미 15:42 에 10 월 13 일 13 일에 언급되었습니다 . 그러나 그것은 for.. of멋지다. 보다 짧은 for each... in.
— manatwork

2
배열 이해 구문이 잘못된 것 같습니다. 설명서 에 따르면 Python과 같아야합니다 b = [s(x) for (x of a)].
— manatwork

@manatwork 위의 샘플들은 Traceur의 REPL에서 잘 작동합니다.
— Florent

Traceur에 대해서는 전혀 모르지만 ECMAScript를 언급하고 Mozilla 설명서를 가리 켰습니다. 그리고 그것들 중 어느 것도 배열 이해력 이 당신이 쓴 것처럼 보이지 않습니다.
— manatwork

1
배열 이해는 실제로 중간 쯤에 당겨졌습니다.
— Isiah Meadows

9

학대 리터럴

최근 샘플 : "c"대문자인지 소문자 인지 , 문자가 아닌지 중요하지 않습니다.

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

3
어떻게 작동합니까?
— 암소 ck

2
@Cowsquack가 String({})제공합니다 "[object Object]".
— Dennis

8

숫자가 부울로 바뀌는 방법을 사용하여 숫자를 비교하는 방법 :

무언가가 양수 인지 확인하려면 해당 양을 빼고 ifand 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
— Ry-

5
ECMAScript 6 : let foo = () => bar;위의 골프 코드보다 짧습니다.
— Isiah Meadows

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)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.